Arrays en PHP

Un array (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 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 un array pueden ser otros array, también es posible crear árboles y array 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.

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(  key =>  value
     , ...
     )
// key puede ser un integer o string
// value puede ser cualquier valor
<?php
$arr = array("foo" => "bar", 12 => true);
echo $arr[“foo”]; // bar
echo $arr[12];    // 1
?>

Un key puede ser un integer o bien 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 key serán truncados a valores tipo integer. Los tipos de arrays indexados y asociativos son el mismo tipo en PHP, el cual pueden contener índices tipo integer o string.

Un valor puede ser de cualquier tipo en PHP.

Nota:

Intentar acceder a un array cuya key no está defina es lo mismo que acceder a cualquier otra variable no definida: Se producirá un error de nivel E_NOTICE, y el resultado será NULL.

<?php
$arr = array("somearray" => array(6 => 5, 13 => 9, "a" => 42));
echo $arr[“somearray”][6];    // 5
echo $arr[“somearray”][13];   // 9
echo $arr[“somearray”][“a”];  // 42
?>

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

<?php
// Este array es lo mismo que...
array(5 => 43, 32, 56, "b" => 12);
// …este array
array(5 => 43, 6 => 32, 7 => 56, “b” => 12);
?>

Advertencia

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

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

Arrays y objetos no pueden ser usados como keys. Al hacerlo se producirá una advertencia: Illegal offset type.

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

Es posible modificar un array existente al definir valores explícitamente en él.

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

$arr[key] = value;
$arr[] = value;
// key puede ser un integer o un string
// value puede ser cualquier valor

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

<?php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56;    // Esto es igual que $arr[13] = 56;
// en este punto del script

$arr[“x”] = 42; // Esto agrega un nuevo elemento a la
// array con la key “x”

unset($arr[5]); // Esto elimina el elemento del array

unset($arr);    // Esto elimina el array completamente
?>

Nota:

Como se mencionó anteriormente, si no se especifica una key, entonces se toma el máximo de los índices integer existentes, y la nueva key será ese valor máximo más 1. Si no existen índices integer aun, la clave será 0 (cero).

Note que el entero máximo usado en la key para este caso no necesita existir actualmente en el array. Tan solo debe haber existido en el array en algún punto desde que el array haya sido re-indexado. El siguiente ejemplo ilustra este caso:

<?php
// Crea un array simple.
$array = array(1, 2, 3, 4, 5);
print_r($array);
// Ahora eliminar cada ítem, pero dejar el array mismo intacto:
foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);

// Agregar un ítem (note que la nueva key es 5, en lugar de 0).
$array[] = 6;
print_r($array);

// Re-indexar:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>

El resultado del ejemplo sería:

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

  • array_change_key_case — Cambia todas las claves en un array
  • array_chunk — Divide un array en fragmentos
  • array_combine — Crea un nuevo array, usando una matriz para las claves y otra para sus valores
  • array_count_values — Cuenta todos los valores de un array
  • array_diff_assoc — Calcula la diferencia entre arrays con un chequeo adicional de índices
  • array_diff_key — Calcula la diferencia entre arrays usando las keys para la comparación
  • array_diff_uassoc — Calcula la diferencia entre arrays con un chequeo adicional de índices que se realiza por una función de devolución de llamada suministrada por el usuario
  • array_diff_ukey — Calcula la diferencia entre arrays usando una función de devolución de llamada en las keys para comparación
  • array_diff — Calcula la diferencia entre arrays
  • array_fill_keys — Llena un array con valores, especificando las keys
  • array_fill — Llena un array con valores
  • array_filter — Filtra elementos de un array usando una función de devolución de llamada
  • array_flip — Intercambia todas las keys con sus valores asociados en un array
  • array_intersect_assoc — Calcula la intersección de arrays con un chequeo adicional de índices
  • array_intersect_key — Calcula la intersección de arrays usando las keys para la comparación
  • array_intersect_uassoc — Calcula la intersección de arrays con un chequeo adicional de índices que se realiza por una función de devolución de llamada
  • array_intersect_ukey — Calcula la intersección de arrays usando una función de devolución de llamada en las keys para la comparación
  • array_intersect — Calcula la intersección de arrays
  • array_key_exists — Verifica si el índice o clave dada existe en el array
  • array_keys — Devuelve todas las claves de un array o un subconjunto de claves de un array
  • array_map — Aplica la llamada de retorno especificada a los elementos de los dados
  • array_merge_recursive — Une dos o más arrays recursivamente
  • array_merge — Combina dos o más arrays
  • array_multisort — Ordena múltiples arrays, o arrays multi-dimensionales
  • array_pad — Rellena un array a la longitud especificada con un valor
  • array_pop — Extrae el último elemento del final del array
  • array_product — Calcula el producto de los valores en el array
  • array_push — Inserta uno o más elementos al final de un array
  • array_rand — Selecciona una o más entradas aleatorias de un array
  • array_reduce — Reduce iterativamente una matriz a un solo valor usando una función llamada de retorno
  • array_replace_recursive — Reemplaza los elementos de los arrays pasados al primer array de forma recursiva
  • array_replace — Remplaza los elementos de los arrays pasados en el primer array
  • array_reverse — Devuelve un array con los elementos en orden inverso
  • array_search — Busca un valor determinado en un array y devuelve la clave correspondiente en caso de éxito
  • array_shift — Quita un elemento del principio del array
  • array_slice — Extrae una parte de un array
  • array_splice — Elimina una porción del array y la reemplaza con algo
  • array_sum — Calcula la suma de los valores en un array
  • array_udiff_assoc — Computa la diferencia entre arrays con una comprobación de indices adicional, compara la información mediante una función de llamada de retorno
  • array_udiff_uassoc — Computa la diferencia entre arrays con una verificación de índices adicional, compara la información y los índices mediante una función de llamada de retorno
  • array_udiff — Computa la diferencia entre arrays, usando una llamada de retorno para la comparación de datos
  • array_uintersect_assoc — Computa la intersección de arrays con una comprobación de índices adicional, compara la información mediante una función de llamada de retorno
  • array_uintersect_uassoc — Computa la intersección de arrays con una comprobación de índices adicional, compara la información y los índices mediante funciones de llamada de retorno
  • array_uintersect — Computa una intersección de arrays, compara la información mediante una función de llamada de retorno
  • array_unique — Elimina valores duplicados de un array
  • array_unshift — Añadir al inicio de un array uno a más elementos
  • array_values — Devuelve todos los valores de un array
  • array_walk_recursive — Aplicar una función de usuario recursivamente a cada miembro de un array
  • array_walk — Aplicar una función de usuario a cada miembro de un array
  • array — Crea un array
  • arsort — Ordena un array en orden inverso y mantiene la asociación de índices
  • asort — Ordena un array y mantiene la asociación de índices
  • compact — Crear un array que contiene variables y sus valores
  • count — Cuenta todos los elementos de un array o en un objecto
  • current — Devuelve el elemento actual en un array
  • each — Devolver el par clave/valor actual de un array y avanzar el cursor del array
  • end — Establece el puntero intero de un array a su último elemento
  • extract — Importar variables a la tabla de símbolos actual desde un array
  • in_array — Comprueba si un valor existe en un array usando comparación flexible
  • key — Obtiene una clave de un array
  • krsort — Ordena un array por clave en orden inverso
  • ksort — Ordena un array por clave
  • list — Asigna variables como si fuera un array
  • natcasesort — Ordenar un array usando un algoritmo de “orden natural” insensible a mayúsculas-minúsculas
  • natsort — Ordena un array usando un algoritmo de “orden natural”
  • next — Avanza el puntero interno de un array
  • pos — Alias de current
  • prev — Rebobina el puntero interno del array
  • range — Crear un array que contiene un rango de elementos
  • reset — Establece el puntero interno de un array a su primer elemento
  • rsort — Ordena un array en orden inverso
  • shuffle — Mezcla un array
  • sizeof — Alias de count
  • sort — Ordena un array
  • uasort — Ordena un array con una función de comparación definida por el usuario y mantiene la asociación de índices
  • uksort — Ordena un array según sus claves usando una función de comparación definida por el usuario
  • usort — Ordena un array según sus valores usando una función de comparación definida por el usuario

Nota:

La función unset() le permite eliminar keys de un array. Tenga en cuenta que el array no es re-indexado. Si desea el comportamiento real de “eliminar y desplazar”, el array puede ser re-indexado usando la función array_values().

<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* producirá un array que hubiera sido definida como
$a = array(1 => 'one', 3 => 'three');
y NO
$a = array(1 => 'one', 2 =>'three');
*/
$b = array_values($a);
// Ahora $b es array(0 => ‘one’, 1 =>’three’)
?>

La estructura de control foreach existe específicamente para arrays. Ésta provee una manera fácil de recorrer un array.

Recomendaciones sobre arrays y cosas a evitar

¿Por qué es incorrecto $foo[bar]?

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

<?php
$foo[bar] = 'enemy';
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 (un string sin comillas que no corresponda con símbolo conocido alguno) en un string 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 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);
// Array simple:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "\nRevisando $i: \n";
echo "Mal: " . $array['$i'] . "\n";
echo "Bien: " . $array[$i] . "\n";
echo "Mal: {$array['$i']}\n";
echo "Bien: {$array[$i]}\n";
}
?>

El resultado del ejemplo sería:

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);
$arr = array(‘fruit’ => ‘apple’, ‘veggie’ => ‘carrot’);

// Correcto
print $arr[‘fruit’];  // apple
print $arr[‘veggie’]; // carrot

// Incorrecto. Esto funciona pero también genera un error de PHP de
// nivel E_NOTICE ya que no hay definida una constante llamada fruit
//
// Notice: Use of undefined constant fruit – assumed ‘fruit’ in…
print $arr[fruit];    // apple

// Esto define una constante para demostrar lo que pasa. El valor ‘veggie’
// es asignado a una constante llamada fruit.
define(‘fruit’, ‘veggie’);

// Note la diferencia ahora
print $arr[‘fruit’];  // apple
print $arr[fruit];    // carrot

// 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 “Hello $arr[fruit]”;      // Hello apple

// Con una excepción, los corchetes que rodean las matrices al
// interior de cadenas permiten el uso de constantes
print “Hello {$arr[fruit]}”;    // Hello carrot
print “Hello {$arr[‘fruit’]}”;  // Hello apple

// 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 “Hello $arr[‘fruit’]”;
print “Hello $_GET[‘foo’]”;

// La concatenación es otra opción
print “Hello ” . $arr[‘fruit’]; // Hello apple
?>

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 $arr[somefunc($bar)];
?>

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

<?php
$error_descriptions[E_ERROR]   = "Un error fatal ha ocurrido";
$error_descriptions[E_WARNING] = "PHP produjo una advertencia";
$error_descriptions[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
$error_descriptions[1] = "Un error fatal ha ocurrido";
$error_descriptions[2] = "PHP produjo una advertencia";
$error_descriptions[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.

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é, así como la sección sobre procesamiento de variables en cadenas.

Conversión a array

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

Si convierte un object a un array, el resultado es un array cuyos elementos son las propiedados del object. Las keys 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 array, obtiene un array vacío.

Comparación

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

Ejemplos

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

<?php
// Esto:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name'  => 'apple',
4        // la clave será 0
);
$b = array(‘a’, ‘b’, ‘c’);

// . . .es completamente equivalente a
$a = array();
$a[‘color’] = ‘red’;
$a[‘taste’] = ‘sweet’;
$a[‘shape’] = ‘round’;
$a[‘name’]  = ‘apple’;
$a[]        = 4;        // la clave será 0

$b = array();
$b[] = ‘a’;
$b[] = ‘b’;
$b[] = ‘c’;

// Después de que se ejecute el código, $a será el array
// array(‘color’ => ‘red’, ‘taste’ => ‘sweet’, ‘shape’ => ‘round’,
// ‘name’ => ‘apple’, 0 => 4), y $b será el array
// array(0 => ‘a’, 1 => ‘b’, 2 => ‘c’), o simplemente array(‘a’, ‘b’, ‘c’).
?>

Ejemplo #1 Uso de array()

<?php
// Array como mapa de propiedades
$map = array( 'version'    => 4,
'OS'         => 'Linux',
'lang'       => 'english',
'short_tags' => true
);
// Keys estrictamente numéricas
$array = array( 7,
8,
0,
156,
-10
);
// esto es lo mismo que array(0 => 7, 1 => 8, …)

$switching = array(         10, // key = 0
5    =>  6,
3    =>  7,
‘a’  =>  4,
11, // key = 6 (el índice entero máximo era 5)
‘8’  =>  2, // key = 8 (integer!)
’02’ => 77, // key = ’02’
0    => 12  // el valor 10 será reemplazado por 12
);

// array vacío
$empty = array();
?>

Ejemplo #2 Colección

<?php
$colors = array('rojo', 'azul', 'verde', 'amarillo');
foreach ($colors as $color) {
echo “¿Le gusta el $color?\n”;
}

?>

El resultado del ejemplo sería:

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

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

Ejemplo #3 Cambiando elemento en el bucle

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

print_r($colors);
?>

El resultado del ejemplo sería:

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

Este ejemplo crea un array con base uno.

Ejemplo #4 Índice con base 1

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

El resultado del ejemplo sería:

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

Ejemplo #5 Llenado de un array

<?php
// llenar un array con todos los ítems de un directorio
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>

Los Arrays son ordenados. El orden puede ser modificado usando varias funciones de ordenado. Vea la sección sobre funciones de arrays para más información. La función count() puede ser usada para contar el número de elementos en un array.

Ejemplo #6 Ordenado de un array

<?php
sort($files);
print_r($files);
?>

Dado que el valor de un array puede ser cualquier cosa, también puede ser otro array. De esta forma es posible crear arrays recursivas y multi-dimensionales.

Ejemplo #7 Arrays recursivos y multi-dimensionales

<?php
$fruits = array ( "fruits"  => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes"   => array (      "first",
5 => "second",
"third"
)
);
// Algunos ejemplos que hacen referencia a los valores del array anterior
echo $fruits[“holes”][5];    // prints “second”
echo $fruits[“fruits”][“a”]; // prints “orange”
unset($fruits[“holes”][0]);  // remove “first”

// Crear una nueva array multi-dimensional
$juices[“apple”][“green”] = “good”;
?>

La asignación de arrays siempre involucra la copia de valores. Use el operador de referencia para copiar un array por referencia.

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 ha cambiado,
// $arr1 sigue siendo array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // ahora $arr1 y $arr3 son iguales

?>