Cadenas
Objetos
Tipos
PHP Manual

## Matrices

Una valor array en PHP es en realidad un mapa ordenado. Un mapa es un tipo de datos que asocia valores con claves. Este tipo es optimizado para varios usos diferentes; puede ser usado como una matriz real, una lista (vector), tabla asociativa (caso particular de implementación de un mapa), diccionario, colección, pila, cola y probablemente más. Ya que los valores de una matriz pueden ser otras matrices, también es posible crear árboles y matrices multidimensionales.

Una explicación sobre tales estructuras de datos se encuentra por fuera del propósito de este manual, pero encontrará al menos un ejemplo de cada uno de ellos. Para más información, consulte la extensa literatura que existe sobre este amplio tema.

### Sintaxis

#### Especificación con array()

Un valor array puede ser creado por la construcción de lenguaje array(). Ésta toma un cierto número de parejas clave => valor separadas con coma.

    array(  clave =>  valor
         , ...
         )
    // clave puede ser un integer o string
    // valor puede ser cualquier valor

`<?php
$matriz = array("foo" => "bar", 12 => true);
echo $matriz["foo"]; // bar
echo $matriz[12]; // 1
?>`

Una clave puede ser un integer o un string. Si una clave es la representación estándar de un integer, será interpretada como tal (es decir, "8" será interpretado como 8, mientras que "08" será interpretado como "08"). Los valores float en clave serán truncados a valores tipo integer. Las matrices indexadas y las asociativas son el mismo tipo en PHP, el cual puede contener índices tipo entero o cadena.

Un valor puede ser de cualquier tipo en PHP.

`<?php
$matriz = array("unamatriz" => array(6 => 5, 13 => 9, "a" => 42));
echo $matriz["unamatriz"][6]; // 5
echo $matriz["unamatriz"][13]; // 9
echo $matriz["unamatriz"]["a"]; // 42
?>`

Si no especifica una clave para un valor dado, entonces es usado el máximo de los índices enteros, y la nueva clave será ese valor máximo más 1. Si se especifica una clave que ya tiene un valor asignado, ése valor será sobrescrito.

`<?php
// Esta matriz es la misma que ...
array(5 => 43, 32, 56, "b" => 12);
// ...esta matriz
array(5 => 43, 6 => 32, 7 => 56, "b" => 12);
?>`
Warning

Antes de PHP 4.3.0, agregar un elemento a una matriz cuya clave máxima actual es un valor negativo creaba una nueva clave como se ha descrito anteriormente. A partir de PHP 4.3.0, la nueva clave será 0.

Al usar `TRUE` como clave, el valor será evaluado al integer 1. Al usar `FALSE` como clave, el valor será evaluado al integer 0. Al usar `NULL` como clave, el valor será evaluado a una cadena vacía. El uso de una cadena vacía como clave creará (o reemplazará) una clave con la cadena vacía y su valor; no es lo mismo que usar corchetes vacíos.

Las matrices y los objetos no pueden ser usados como claves. Al hacerlo se producirá una advertencia: Illegal offset type.

#### Creación/modificación con sintaxis de corchetes cuadrados

Es posible modificar una matriz existente al definir valores explícitamente en ella.

Esto es posible al asignar valores a la matriz al mismo tiempo que se especifica la clave entre corchetes. También es posible omitir la clave, lo que resulta en una pareja de corchetes vacíos ([]).

    $matriz[clave] = valor;
    $matriz[] = valor;
    // clave puede ser un integer o string
    // valor puede ser cualquier valor

Si $matriz no existe aun, será creada, así que ésta es también una forma alternativa de crear una matriz. Para modificar un cierto valor, simplemente asigne un nuevo valor a un elemento usando su clave. Para remover una pareja clave/valor, use la función unset() sobre ella.

`<?php
$matriz = array(5 => 1, 12 => 2);
$matriz[] = 56; // Esto es igual que $matriz[13] = 56;
// en este punto del script
$matriz["x"] = 42; // Esto agrega un nuevo elemento a la
// matriz con la clave "x"
unset($matriz[5]); // Esto elimina el elemento de la matriz
unset($matriz); // Esto elimina la matriz completa
***
?>`

> Note: Como se menciona anteriormente, si no se especifica una clave, entonces se toma el máximo de los índices enteros existentes, y la nueva clave será ese valor máximo más 1. Si no existen índices enteros aun, la clave será 0 (cero). Si se especifica una clave que ya tenía un valor asignado, el valor será reemplazado.
> Note que la clave entera máxima usada para este caso no necesita existir actualmente en la matriz. Tan solo debe haber existido en la matriz en algún punto desde que la matriz haya sido re-indexada. El siguiente ejemplo ilustra este caso:

> `<?php
> // Crear una matriz simple.
> $matriz = array(1, 2, 3, 4, 5);
> print_r($matriz);
> // Ahora eliminar cada ítem, pero dejar la matriz misma intacta:
> foreach ($matriz as $i => $valor) {
> unset($matriz[$i]);
> }
> print_r($matriz);
> // Agregar un ítem (note que la nueva clave es 5, en lugar de 0).
> $matriz[] = 6;
> print_r($matriz);
> // Re-indexar:
> $matriz = array_values($matriz);
> $matriz[] = 7;
> print_r($matriz);
> ?>`

> El resultado del ejemplo seria:

>     Array
>     (
>         [0] => 1
>         [1] => 2
>         [2] => 3
>         [3] => 4
>         [4] => 5
>     )
>     Array
>     (
>     )
>     Array
>     (
>         [5] => 6
>     )
>     Array
>     (
>         [0] => 6
>         [1] => 7
>     )

### Funciones útiles

Existe un buen número de funciones útiles para trabajar con matrices. Consulte la sección funciones de matrices.

> Note: La función unset() le permite remover claves de una matriz. Tenga en cuenta que la matriz no es re-indexada. Si desea el comportamiento real de "eliminar y desplazar", la matriz puede ser re-indexada usando la función array_values().

> `<?php
> $a = array(1 => 'uno', 2 => 'dos', 3 => 'tres');
> unset($a[2]);
> /* producirá una matriz que hubiera sido definida como
> $a = array(1 => 'uno', 3 => 'tres');
> y NO
> $a = array(1 => 'uno', 2 =>'tres');
> */
> $b = array_values($a);
> // Ahora $b es array(0 => 'uno', 1 =>'tres')
> ?>`

La estructura de control foreach existe específicamente para las matrices. Ésta provee una manera fácil de recorrer una matriz.

### Recomendaciones sobre matrices y cosas a evitar

#### ¿Porqué es incorrecto $foo[bar]?

Siempre deben usarse comillas alrededor de un índice de matriz tipo cadena literal. Por ejemplo, $foo['bar'] es correcto, mientras que $foo[bar] no lo es. ¿Pero porqué? Es común encontrar este tipo de sintaxis en scripts viejos:

`<?php
$foo[bar] = 'enemigo';
echo $foo[bar];
// etc
?>`

Esto está mal, pero funciona. La razón es que este código tiene una constante indefinida (bar) en lugar de un valor string ('bar' - note las comillas). Puede que en el futuro PHP defina constantes que, desafortunadamente para tal tipo de código, tengan el mismo nombre. Funciona porque PHP automáticamente convierte una cadena pura (una cadena sin comillas que no corresponda con símbolo conocido alguno) en una cadena que contiene la cadena pura. Por ejemplo, si no se ha definido una constante llamada `bar`, entonces PHP reemplazará su valor por la cadena 'bar' y usará ésta última.

> Note: Esto no quiere decir que siempre haya que usar comillas en la clave. No use comillas con claves que sean constantes o variables, ya que en tal caso PHP no podrá interpretar sus valores.

> `<?php
> error_reporting(E_ALL);
> ini_set('display_errors', true);
> ini_set('html_errors', false);
> // Matriz simple:
> $matriz = array(1, 2);
> $conteo = count($matriz);
> for ($i = 0; $i < $conteo; $i++) {
> echo "\nRevisando $i: \n";
> echo "Mal: " . $matriz['$i'] . "\n";
> echo "Bien: " . $matriz[$i] . "\n";
> echo "Mal: {$matriz['$i']}\n";
> echo "Bien: {$matriz[$i]}\n";
> }
> ?>`

> El resultado del ejemplo seria:

>     Revisando 0:
>     Notice: Undefined index:  $i in /path/to/script.html on line 9
>     Mal:
>     Bien: 1
>     Notice: Undefined index:  $i in /path/to/script.html on line 11
>     Mal:
>     Bien: 1

>     Revisando 1:
>     Notice: Undefined index:  $i in /path/to/script.html on line 9
>     Mal:
>     Bien: 2
>     Notice: Undefined index:  $i in /path/to/script.html on line 11
>     Mal:
>     Bien: 2
>     ***

Más ejemplos para demostrar este comportamiento:

`<?php
// Mostrar todos los errores
error_reporting(E_ALL);
$matriz = array('fruta' => 'manzana', 'vegetal' => 'zanahoria');
// Correcto
print $matriz['fruta']; // manzana
print $matriz['vegetal']; // zanahoria
// Incorrecto. Esto funciona pero también genera un error de PHP de
// nivel E_NOTICE ya que no hay definida una constante llamada fruta
//
// Notice: Use of undefined constant fruta - assumed 'fruta' in...
print $matriz[fruta]; // manzana
// Esto define una constante para demostrar lo que pasa. El valor 'vegetal'
// es asignado a una constante llamada fruta.
define('fruta', 'vegetal');
// Note la diferencia ahora
print $matriz['fruta']; // manzana
print $matriz[fruta]; // zanahoria
// Lo siguiente está bien ya que se encuentra al interior de una
// cadena. Las constantes no son procesadas al interior de
// cadenas, así que no se produce un error E_NOTICE aquí
print "Hola $matriz[fruta]"; // Hola manzana
// Con una excepción, los corchetes que rodean las matrices al
// interior de cadenas permiten el uso de constantes
print "Hola {$matriz[fruta]}"; // Hola zanahoria
print "Hola {$matriz['fruta']}"; // Hola manzana
// Esto no funciona, resulta en un error de intérprete como:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Esto por supuesto se aplica también al uso de superglobales en cadenas
print "Hola $matriz['fruta']";
print "Hola $_GET['foo']";
// La concatenación es otra opción
print "Hola " . $matriz['fruta']; // Hola manzana
?>`

Cuando se habilita error_reporting() para mostrar errores de nivel `E_NOTICE` (como por ejemplo definiendo el valor `E_ALL`), este tipo de usos serán inmediatamente visibles. Por omisión, error_reporting se encuentra configurado para no mostrarlos.

Tal y como se indica en la sección de sintaxis, lo que existe entre los corchetes cuadrados ('[' y ']') debe ser una expresión. Esto quiere decir que código como el siguiente funciona:

`<?php
echo $matriz[alguna_funcion($bar)];
?>`

Este es un ejemplo del uso de un valor devuelto por una función como índice de matriz. PHP también conoce las constantes:

`<?php
$descripciones_de_error[E_ERROR] = "Un error fatal ha ocurrido";
$descripciones_de_error[E_WARNING] = "PHP produjo una advertencia";
$descripciones_de_error[E_NOTICE] = "Esta es una noticia informal";
?>`

Note que E_ERROR es también un identificador válido, asi como bar en el primer ejemplo. Pero el último ejemplo es equivalente a escribir:

`<?php
$descripciones_de_error[1] = "Un error fatal ha ocurrido";
$descripciones_de_error[2] = "PHP produjo una advertencia";
$descripciones_de_error[8] = "Esta es una noticia informal";
?>`

ya que E_ERROR es igual a 1, etc.

##### ¿Entonces porqué está mal?

En algún momento en el futuro, puede que el equipo de PHP quiera usar otra constante o palabra clave, o una constante proveniente de otro código puede interferir. Por ejemplo, en este momento no puede usar las palabras empty y default de esta forma, ya que son palabras clave reservadas.

> Note: Reiterando, al interior de un valor string entre comillas dobles, es válido no rodear los índices de matriz con comillas, así que "$foo[bar]" es válido. Consulte los ejemplos anteriores para más detalles sobre el porqué, así como la sección sobre procesamiento de variables en cadenas.

### Conversión a matriz

Para cualquiera de los tipos: integer, float, string, boolean y resource, convertir un valor a un array resulta en una matriz con un solo elemento, con índice 0, y el valor del escalar que fue convertido. En otras palabras, (array)$valorEscalar es exactamente lo mismo que array($valorEscalar).

Si convierte un object a un array, el resultado es una matriz cuyos elementos son las propiedados del objeto. Las claves son los nombres de las variables miembro, con algunas excepciones notables: las variables privadas tienen el nombre de la clase al comienzo del nombre de la variable; las variables protegidas tienen un caracter '*' al comienzo del nombre de la variable. Estos valores adicionados al inicio tienen bytes nulos a los lados. Esto puede resultar en algunos comportamientos inesperados:

`<?php
class A {
private $A; // Este campo se convertirá en '\0A\0A'
}
class B extends A {
private $A; // Este campo se convertirá en '\0B\0A'
public $AA; // Este campo se convertirá en 'AA'
}
var_dump((array) new B());
?>`

En el ejemplo anterior parecerá que se tienen dos claves llamadas 'AA', aunque en realidad una de ellas se llama '\0A\0A'.

Si convierte un valor `NULL` a matriz, obtiene una matriz vacía.

### Comparación

Es posible comparar matrices con la función array_diff() y mediante operadores de matriz.

### Ejemplos

El tipo matriz en PHP es bastante versátil. Aquí hay algunos ejempos:

`<?php
// esto
$a = array( 'color' => 'rojo',
'sabor' => 'dulce',
'forma' => 'redonda',
'nombre' => 'manzana',
4 // la clave será 0
);
// es completamente equivalente a
$a['color'] = 'rojo';
$a['sabor'] = 'dulce';
$a['forma'] = 'redonda';
$a['nombre'] = 'manzana';
$a[] = 4; // la clave será 0
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// resultará en la matriz array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// o simplemente array('a', 'b', 'c')
?>`

Example #1 Uso de array()

`<?php
// Array como mapa de propiedades
$mapa = array( 'versión' => 4,
'SO' => 'Linux',
'idioma' => 'inglés',
'etiquetas_cortas' => true
);
// claves estrictamente numéricas
$matriz = array( 7,
8,
0,
156,
-10
);
// esto es lo mismo que array(0 => 7, 1 => 8, ...)
$cambios = array( 10, // clave = 0
5 => 6,
3 => 7,
'a' => 4,
11, // clave = 6 (el índice entero máximo era 5)
'8' => 2, // clave = 8 (¡entero!)
'02' => 77, // clave = '02'
0 => 12 // el valor 10 será reemplazado por 12
);
// matriz vacía
$vacio = array();
?>`

Example #2 Colección

`<?php
$colores = array('rojo', 'azul', 'verde', 'amarillo');
foreach ($colores as $color) {
echo "¿Le gusta el $color?\n";
}
?>`

El resultado del ejemplo seria:

    ¿Le gusta el rojo?
    ¿Le gusta el azul?
    ¿Le gusta el verde?
    ¿Le gusta el amarillo?

Modificar los valores de la matriz directamente es posible a partir de PHP 5, pasándolos por referencia. Las versiones anteriores necesitan una solución alternativa:

Example #3 Colección

`<?php
// PHP 5
foreach ($colores as &$color) {
$color = strtoupper($color);
}
unset($color); /* se asegura de que escrituras subsiguientes a $color
no modifiquen el último elemento de la matriz */
// Alternativa para versiones anteriores
foreach ($colores as $clave => $color) {
$colores[$clave] = strtoupper($color);
}
print_r($colores);
?>`

El resultado del ejemplo seria:

    Array
    (
        [0] => ROJO
        [1] => AZUL
        [2] => VERDE
        [3] => AMARILLO
    )

Este ejemplo crea una matriz con base uno.

Example #4 Índice con base 1

`<?php
$primercuarto = array(1 => 'Enero', 'Febrero', 'Marzo');
print_r($primercuarto);
?>`

El resultado del ejemplo seria:

    Array
    (
        [1] => 'Enero'
        [2] => 'Febrero'
        [3] => 'Marzo'
    )

Example #5 Llenado de una matriz

`<?php
// llenar una matriz con todos los ítems de un directorio
$gestor = opendir('.');
while (false !== ($archivo = readdir($gestor))) {
$archivos[] = $archivo;
}
closedir($gestor);
?>`

Las matrices son ordenadas. El orden puede ser modificado usando varias funciones de ordenamiento. Vea la sección sobre funciones de matrices para más información. La función count() puede ser usada para contar el número de elementos en una matriz.

Example #6 Ordenamiento de una matriz

`<?php
sort($archivos);
print_r($archivos);
?>`

Dado que el valor de una matriz puede ser cualquier cosa, también puede ser otra matriz. De esta forma es posible crear matrices recursivas y multi-dimensionales.

Example #7 Matrices recursivas y multi-dimensionales

`<?php
$frutas = array ( "frutas" => array ( "a" => "naranja",
"b" => "banano",
"c" => "manzana"
),
"números" => array ( 1,
2,
3,
4,
5,
6
),
"hoyos" => array ( "primero",
5 => "segundo",
"tercero"
)
);
// Algunos ejemplos que hacen referencia a los valores de la matriz anterior
echo $frutas["hoyos"][5]; // imprime "segundo"
echo $frutas["frutas"]["a"]; // imprime "naranja"
unset($frutas["hoyos"][0]); // elimina "primero"
// Crear una nueva matriz multi-dimensional
$jugos["manzana"]["verde"] = "bien";
?>`

La asignación de matrices siempre involucra la copia de valores. También quiere decir que el apuntador interno de matriz usado por current() y otras funciones similares es reestablecido. Use el operador de referencia para copiar una matriz por referencia.

`<?php
$matriz1 = array(2, 3);
$matriz2 = $matriz1;
$matriz2[] = 4; // $matriz2 cambia,
// $matriz1 sigue siendo array(2, 3)
$matriz3 = &$matriz1;
$matriz3[] = 4; // ahora $matriz1 y $matriz3 son iguales
?>`

Cadenas
Objetos
Tipos
PHP Manual