Matrices

Una matriz en PHP es en realidad un mapa ordenado. Un mapa es un tipo de datos que asocia valores con claves. Este tipo es optimizado en varias formas, de modo que puede usarlo como una matriz real, o una lista (vector), tabla asociativa (caso particular de implementación de un mapa), diccionario, colección, pila, cola y probablemente más. Ya que puede tener otra matriz PHP como valor, es realmente fácil simular árboles.

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, le referimos a literatura externa sobre este amplio tema.

Sintaxis

Especificación con array()

Un 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 flotantes en clave serán truncados a valores tipo integer. No existen tipos diferentes para matrices indexadas y asociativas en PHP; sólo existe un tipo de matriz, 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 + 1. Si 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);
?>

Aviso

A partir de PHP 4.3.0, el comportamiento de generación de índices descrito ha cambiado. Ahora, si agrega un elemento a una matriz cuya clave máxima actual es un valor negativo, entonces la siguiente clave creada será cero (0). Anteriormente, el nuevo índice hubiera sido establecido a la clave mayor existente + 1, al igual que con los índices positivos.

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.

No es posible usar matrices u objetos 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, agregar una pareja vacía de corchetes ("[]") al nombre de la variable en ese caso.
$matriz[clave] = valor;
$matriz[] = valor;
// clave puede ser un integer o string
// valor puede ser cualquier valor
Si $matriz no existe aun, ésta será creada. De modo que esta es también una forma alternativa de especificar una matriz. Para modificar un cierto valor, simplemente asigne un nuevo valor a un elemento especificado con su clave. Si desea remover una pareja clave/valor, necesita eliminarla mediante unset().

<?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
?>

Nota: Como se menciona anteriormente, si provee los corchetes sin ninguna clave especificada, entonces se toma el máximo de los índices enteros existentes, y la nueva clave será ese valor máximo + 1. Si no existen índices enteros aun, la clave será 0 (cero). Si especifica una clave que ya tenía un valor asignado, el valor será reemplazado.

Aviso

A partir de PHP 4.3.0, el comportamiento de generación de índices descrito ha cambiado. Ahora, si agrega un elemento al final de una matriz en la que la clave máxima actual es negativa, la siguiente clave creada será cero (0). Anteriormente, el nuevo índice hubiera sido definido como la mayor clave + 1, al igual que ocurre con los índices positivos.

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 item, pero dejar la matriz misma intacta:
foreach ($matriz as $i => $valor) {
    unset(
$matriz[$i]);
}
print_r($matriz);

// Agregar un item (note que la nueva clave es 5, en lugar de 0 como
// podria esperarse).
$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.

Nota: La función unset() le permite remover la definición de claves de una matriz. Tenga en cuenta que la matriz NO es re-indexada. Si sólo usa "índices enteros comunes" (comenzando desde cero, incrementando en uno), puede conseguir el efecto de re-indexación usando array_values().

<?php
$a
= array(1 => 'uno', 2 => 'dos', 3 => 'tres');
unset(
$a[2]);
/* producira 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, use $foo['bar'] y no $foo[bar]. ¿Pero qué está mal en $foo[bar]? Es posible que haya visto la siguiente sintaxis en scripts viejos:

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

Esto está mal, pero funciona. Entonces, ¿porqué está mal? La razón es que este código tiene una constante indefinida (bar) en lugar de una cadena ('bar' - note las comillas), y puede que en el futuro PHP defina constantes que, desafortunadamente para su 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.

Nota: Esto no quiere decir que siempre haya que usar comillas en la clave. No querrá usar 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";
}
?>

Nota: 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 hecho:

<?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&eacute;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

// Definamos una constante para demostrar lo que pasa. Asignaremos el
// valor 'vegetal' a una constante llamada fruta.
define('fruta', 'vegetal');

// Note la diferencia ahora
print $matriz['fruta'];  // manzana
print $matriz[fruta];    // zanahoria

// Lo siguiente esta bien ya que se encuentra al interior de una
// cadena. Las constantes no son procesadas al interior de
// cadenas, asi que no se produce un error E_NOTICE aqui
print "Hola $matriz[fruta]";  // Hola manzana

// Con una excepcion, 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 interprete como:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Esto se aplica tambien al uso de autoglobales en cadenas, por supuesto
print "Hola $matriz['fruta']";
print
"Hola $_GET['foo']";

// La concatenacion es otra opcion
print "Hola " . $matriz['fruta']; // Hola manzana
?>

Cuando habilita error_reporting() para mostrar errores de nivel E_NOTICE (como por ejemplo definiendo el valor E_ALL) verá estos errores. Por defecto, error_reporting se encuentra configurado para no mostrarlos.

Tal y como se indica en la sección de sintaxis, debe existir una expresión entre los corchetes cuadrados ('[' y ']'). Eso quiere decir que puede escribir cosas como esta:

<?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, tal y como ha podido apreciar aquellas E_* antes.

<?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.

Tal y como lo hemos explicado en los anteriores ejemplos, $foo[bar] aun funciona pero está mal. Funciona, porque debido a su sintaxis, se espera que bar sea una expresión constante. Sin embargo, en este caso no existe una constante con el nombre bar. PHP asume ahora que usted quiso decir bar literalmente, como la cadena "bar", pero que olvidó escribir las comillas.

¿Entonces porqué está mal?

En algún momento en el futuro, el equipo de PHP puede querer usar otra constante o palabra clave, o puede que usted introduzca otra constante en su aplicación, y entonces se ve en problemas. Por ejemplo, en este momento no puede usar las palabras empty y default de esta forma, ya que son palabras clave reservadas especiales.

Nota: 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é, asi 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, si convierte un valor a un array, obtiene una matriz con un elemento (con índice 0), el cual es el valor escalar con el que inició.

Si convierte un object a una matriz, obtiene las propiedades (variables miembro) de ese objeto como los elementos de la matriz. Las claves son los nombres de las variables miembro.

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

Comparación

Es posible comparar matrices con array_diff() y mediante operadores de matriz.

Ejemplos

El tipo matriz en PHP es bastante versátil, así que aquí se presentan algunos ejemplos que demuestran el poder completo de las matrices.

<?php
// esto
$a = array( 'color'  => 'rojo',
            
'sabor'  => 'dulce',
            
'forma'  => 'redonda',
            
'nombre' => 'manzana',
                       
4        // la clave sera 0
          
);

// es completamente equivalente con
$a['color']  = 'rojo';
$a['sabor']  = 'dulce';
$a['forma']  = 'redonda';
$a['nombre'] = 'manzana';
$a[]         = 4;        // la clave sera 0

$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// resultara en la matriz array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// o simplemente array('a', 'b', 'c')
?>

Ejemplo 11-6. Uso de array()

<?php
// Array como mapa de propiedades
$mapa = array( 'version'          => 4,
               
'SO'               => 'Linux',
               
'idioma            => 'ingles',
               '
etiquetas_cortas' => true
            );

// claves estrictamente numericas
$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 indice entero maximo era 5)
                  '
8'  =>  2, // clave = 8 (entero!)
                  '
02' => 77, // clave = '02'
                  0    => 12  // el valor 10 sera reemplazado por 12
                );

// matriz vacia
$vacio = array();
?>

Ejemplo 11-7. Colección

<?php
$colores
= array('rojo', 'azul', 'verde', 'amarillo');

foreach (
$colores as $color) {
    echo
"&iquest;Le gusta el $color?\n";
}

?>

El resultado del ejemplo seria:

&iquest;Le gusta el rojo?
&iquest;Le gusta el azul?
&iquest;Le gusta el verde?
&iquest;Le gusta el amarillo?

Note que actualmente no es posible cambiar los valores de la matriz directamente en un ciclo de ese tipo. Una solución parcial es la siguiente:

Ejemplo 11-8. Colección

<?php
foreach ($colores as $clave => $color) {
    
// no funciona:
    //$color = strtoupper($color);
    
    // funciona:
    
$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.

Ejemplo 11-9. Í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'
)

Ejemplo 11-10. Llenado de una matriz

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

Las matrices son ordenadas. Puede también cambiar el orden usando varias funciones de ordenamiento. Vea la sección sobre funciones de matrices para más información. Puede contar el número de items en una matriz usando la función count().

Ejemplo 11-11. 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.

Ejemplo 11-12. Matrices recursivas y multi-dimensionales

<?php
$frutas
= array ( "frutas"  => array ( "a" => "naranja",
                                       
"b" => "banano",
                                       
"c" => "manzana"
                                     
),
                  
"numeros" => 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";
?>

Debe advertir que la asignación de matrices siempre involucra la copia de valores. Necesita usar 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
?>

Hosting by: hurra.com
Generated: 2007-01-26 18:00:52