Arrays en PHP: indexados, asociativos y multidimensionales
En esta lección
Hasta ahora cada variable guardaba un solo dato. Pero una web maneja colecciones: la lista de productos de una tienda, los socios de un club, las líneas de un pedido, los campos de un formulario. Para eso existe el array, una variable que guarda muchos valores, cada uno identificado por una clave. En esta lección aprenderás a crear arrays indexados y asociativos, a leer, añadir, cambiar y borrar elementos, a inspeccionarlos, a combinarlos en estructuras de varios niveles y a sacar sus valores en variables con la desestructuración.
Qué es un array
Un array es una colección ordenada de pares clave => valor. Piensa en una taquilla de gimnasio: cada casillero tiene un número (la clave) y algo dentro (el valor).
En PHP, el mismo tipo array sirve para dos usos que en otros lenguajes son estructuras distintas:
- Arrays indexados: las claves son números que PHP asigna solo, empezando por 0. Son listas:
["arnés", "casco", "cuerda"]. - Arrays asociativos: las claves son textos que eliges tú. Describen algo con campos con nombre:
["nombre" => "Lucía", "edad" => 29].
Arrays indexados
Se crean con corchetes, separando los valores con comas:
$dias = ["lunes", "martes", "miércoles", "jueves", "viernes"];
$notas = [7.5, 9, 6.25];
$vacio = [];
echo $dias[0], "\n";
echo $dias[4], "\n";
echo $notas[1], "\n";
// lunes
// viernes
// 9
Para leer un elemento escribes el nombre del array y, entre corchetes, su índice (su posición). El primero es el 0, no el 1: en un array de 5 elementos, los índices van de 0 a 4.
Nota: en código antiguo verás la sintaxis
array("lunes", "martes"). Hace exactamente lo mismo; desde PHP 5.4 se usan los corchetes, más cortos.
Cuántos elementos tiene: count
$inscritos = ["Ainhoa", "Marcos", "Julia"];
echo count($inscritos), "\n";
$ultimo = $inscritos[count($inscritos) - 1];
echo $ultimo, "\n";
// 3
// Julia
El último elemento está en la posición count - 1, porque se empieza a contar en 0.
Añadir y modificar elementos
Para añadir un elemento al final, escribe corchetes vacíos. Para modificar uno, asigna un valor nuevo a su índice:
$compra = ["leche", "pan"];
$compra[] = "huevos";
$compra[] = "tomates";
$compra[1] = "pan integral";
echo implode(", ", $compra), "\n";
// leche, pan integral, huevos, tomates
$array[] = valor es la forma más habitual de construir una lista poco a poco, por ejemplo dentro de un bucle o al ir guardando los errores de un formulario.
Ver el contenido: print_r y var_dump
echo no sirve para mostrar un array: imprime solo la palabra Array y un aviso. Para inspeccionarlo mientras programas tienes dos funciones:
$tallas = ["S", "M", "L"];
print_r($tallas);
var_dump($tallas);
// Array
// (
// [0] => S
// [1] => M
// [2] => L
// )
// array(3) {
// [0]=>
// string(1) "S"
// [1]=>
// string(1) "M"
// [2]=>
// string(1) "L"
// }
print_r() es más legible; var_dump() añade los tipos, útil cuando dudas de si algo es "1" o 1. En el navegador, rodéalos con <pre> para que se respeten los saltos de línea.
Arrays asociativos
En un array asociativo eliges tú las claves, normalmente textos, con el operador =>:
$socio = [
"nombre" => "Lucía",
"edad" => 29,
"nivel" => "intermedio",
"alCorriente" => true,
];
echo $socio["nombre"], " tiene ", $socio["edad"], " años\n";
$socio["nivel"] = "avanzado"; // modificar
$socio["telefono"] = "600123456"; // añadir una clave nueva
echo count($socio), "\n";
// Lucía tiene 29 años
// 5
Son perfectos para representar una cosa con varios datos: un socio, un producto, un pedido. Los nombres de las claves hacen que el código se explique solo: $socio["edad"] se entiende mejor que $socio[1].
Las superglobales como $_POST o $_SESSION son arrays asociativos: $_POST["email"] es simplemente leer la clave "email".
Consejo: pon una coma también tras el último elemento cuando escribas un array en varias líneas. PHP lo permite y así, al añadir otro elemento, no se te olvida la coma.
Qué valores pueden ser claves
Las claves solo pueden ser enteros o cadenas. PHP hace algunas conversiones automáticas que conviene conocer:
$datos = [];
$datos["7"] = "a"; // una cadena con un entero se convierte en int
$datos[7] = "b"; // misma clave: sobrescribe
$datos[true] = "c"; // true se convierte en 1
$datos[2.9] = "d"; // los float se cortan: clave 2 (y PHP avisa)
var_dump(array_keys($datos));
// array(3) {
// [0]=>
// int(7)
// [1]=>
// int(1)
// [2]=>
// int(2)
// }
No hace falta memorizarlo: basta con usar claves que sean claramente enteros o textos. Lo importante es saber que "7" y 7 son la misma clave, y que no puede haber dos claves iguales en un array: la segunda sobrescribe a la primera.
Leer claves que pueden no existir
Si lees una clave que no existe, PHP muestra un aviso y devuelve null:
$producto = ["nombre" => "Casco", "precio" => 55];
echo $producto["color"];
// Warning: Undefined array key "color" in ... on line 2
Hay tres formas de evitarlo, según lo que necesites:
$producto = ["nombre" => "Casco", "precio" => 55, "descuento" => null];
// 1. Valor por defecto con ??
$color = $producto["color"] ?? "sin especificar";
echo $color, "\n";
// 2. isset: ¿existe y no es null?
var_dump(isset($producto["precio"]));
var_dump(isset($producto["descuento"]));
// 3. array_key_exists: ¿existe la clave, valga lo que valga?
var_dump(array_key_exists("descuento", $producto));
// sin especificar
// bool(true)
// bool(false)
// bool(true)
La diferencia está en el null: isset() y ?? tratan una clave con valor null como si no existiera; array_key_exists() solo mira si la clave está. En la práctica, ?? cubre la mayoría de casos.
Buscar un valor: in_array
Para saber si un valor (no una clave) está en el array, usa in_array(). Pasa true como tercer argumento para que compare de forma estricta, con ===:
$tallasDisponibles = ["38", "39", "41", "42"];
var_dump(in_array("41", $tallasDisponibles, true));
var_dump(in_array(40, $tallasDisponibles, true));
var_dump(in_array(41, $tallasDisponibles, true));
// bool(true)
// bool(false)
// bool(false)
La última da false porque 41 (entero) no es idéntico a "41" (texto). Sin el true, PHP los consideraría iguales. Es la misma diferencia entre == y === que viste en Operadores. Si además quieres saber en qué posición está, usa array_search(), que encontrarás en Funciones de arrays.
Borrar elementos: unset
unset() elimina un elemento por su clave:
$equipo = ["Rosa", "Iván", "Teo", "Nuria"];
unset($equipo[1]);
print_r($equipo);
// Array
// (
// [0] => Rosa
// [2] => Teo
// [3] => Nuria
// )
Fíjate: los índices no se reordenan. Queda un hueco en el 1. Para un foreach da igual, pero si después accedes con $equipo[1] obtendrás un aviso. Si necesitas índices seguidos otra vez, array_values() los renumera:
$equipo = ["Rosa", "Iván", "Teo", "Nuria"];
unset($equipo[1]);
$equipo = array_values($equipo);
print_r($equipo);
// Array
// (
// [0] => Rosa
// [1] => Teo
// [2] => Nuria
// )
Para quitar el primero o el último de una lista existen array_shift() y array_pop(), que verás junto con el resto de funciones en la siguiente lección.
Recorrer un array
La forma natural de recorrer un array es foreach, que explicamos en Bucles. Funciona con los dos tipos de arrays:
$precios = ["entrada" => 11, "bono10" => 95, "mensual" => 45];
foreach ($precios as $tarifa => $precio) {
echo str_pad($tarifa, 10, "."), " $precio €\n";
}
// entrada... 11 €
// bono10.... 95 €
// mensual... 45 €
Y para convertir un array en texto (por ejemplo, una lista separada por comas), implode(), que viste en Cadenas.
Arrays multidimensionales
Un valor de un array puede ser otro array. Así se forman estructuras de varios niveles, llamadas multidimensionales. La más habitual en PHP es una lista de arrays asociativos: cada elemento es una “fila” con sus campos, igual que las filas de una tabla de base de datos.
$cursos = [
["titulo" => "Iniciación", "plazas" => 8, "monitor" => "Sergio"],
["titulo" => "Técnica de pies", "plazas" => 0, "monitor" => "Eva"],
["titulo" => "Autorrescate", "plazas" => 4, "monitor" => "Sergio"],
];
echo $cursos[1]["titulo"], "\n";
echo $cursos[2]["monitor"], "\n";
// Técnica de pies
// Sergio
Para llegar a un dato se encadenan corchetes: primero la fila ([1]) y luego el campo (["titulo"]). Recorrerlo es combinar foreach y claves:
$cursos = [
["titulo" => "Iniciación", "plazas" => 8],
["titulo" => "Técnica de pies", "plazas" => 0],
["titulo" => "Autorrescate", "plazas" => 4],
];
$plazasTotales = 0;
foreach ($cursos as $curso) {
$estado = $curso["plazas"] > 0 ? "{$curso['plazas']} plazas" : "completo";
echo "{$curso['titulo']}: $estado\n";
$plazasTotales += $curso["plazas"];
}
echo "Plazas libres en total: $plazasTotales\n";
// Iniciación: 8 plazas
// Técnica de pies: completo
// Autorrescate: 4 plazas
// Plazas libres en total: 12
Otra estructura frecuente es un array asociativo cuyos valores son listas, por ejemplo para agrupar:
$horarios = [
"lunes" => ["18:00", "20:00"],
"miércoles" => ["17:00", "19:00", "21:00"],
];
$horarios["viernes"][] = "19:30"; // crea la clave y añade la hora
foreach ($horarios as $dia => $horas) {
echo "$dia: " . implode(", ", $horas) . "\n";
}
// lunes: 18:00, 20:00
// miércoles: 17:00, 19:00, 21:00
// viernes: 19:30
Fíjate en la línea de "viernes": si la clave no existe, PHP la crea como un array vacío y añade el elemento. Es una forma cómoda de agrupar datos dentro de un bucle.
Consejo: más de tres niveles de corchetes (
$datos["a"][2]["b"]["c"]) suele indicar que la estructura se ha complicado demasiado. Cuando ocurra, piensa en usar clases.
Desestructuración: sacar valores a variables
La desestructuración asigna varios elementos de un array a variables en una sola línea. Con arrays indexados, se ponen las variables entre corchetes a la izquierda del =:
$coordenadas = [43.46, -3.80];
[$latitud, $longitud] = $coordenadas;
echo "Lat: $latitud, Lon: $longitud\n";
[, $segundo] = ["oro", "plata", "bronce"]; // saltar el primero
echo $segundo, "\n";
// Lat: 43.46, Lon: -3.8
// plata
Con arrays asociativos, indicas qué clave va a cada variable:
$reserva = ["cliente" => "Diego", "personas" => 4, "hora" => "20:30"];
["cliente" => $cliente, "hora" => $hora] = $reserva;
echo "$cliente a las $hora\n";
// Diego a las 20:30
Un truco práctico: intercambiar dos variables sin una auxiliar.
$a = "izquierda";
$b = "derecha";
[$a, $b] = [$b, $a];
echo "$a / $b\n";
// derecha / izquierda
Verás también la función list($a, $b) = ..., que es la forma antigua de hacer lo mismo.
Combinar arrays: spread ...
El operador spread (...) “despliega” los elementos de un array dentro de otro. Sirve para unir listas:
$basico = ["arnés", "casco"];
$extra = ["cuerda", "cintas"];
$equipo = [...$basico, ...$extra, "magnesio"];
echo implode(", ", $equipo), "\n";
// arnés, casco, cuerda, cintas, magnesio
Desde PHP 8.1 también funciona con arrays asociativos. Si una clave se repite, gana la última, lo que es ideal para combinar una configuración por defecto con la del usuario:
$porDefecto = ["idioma" => "es", "tema" => "claro", "avisos" => true];
$usuario = ["tema" => "oscuro"];
$config = [...$porDefecto, ...$usuario];
print_r($config);
// Array
// (
// [idioma] => es
// [tema] => oscuro
// [avisos] => 1
// )
print_r() muestra true como 1. Para unir arrays también existe array_merge(), que hace lo mismo que el spread.
Los arrays se copian al asignarlos
Al asignar un array a otra variable o pasarlo a una función, PHP hace una copia. Cambiar la copia no afecta al original:
$original = [1, 2, 3];
$copia = $original;
$copia[] = 4;
echo count($original), " y ", count($copia), "\n";
// 3 y 4
Esto es distinto de JavaScript, donde los dos nombres apuntarían al mismo array. En PHP es más difícil modificar un array por accidente desde otra parte del código.
Comparar arrays
== comprueba que tengan los mismos pares clave/valor; === exige además el mismo orden y los mismos tipos:
$a = ["x" => 1, "y" => 2];
$b = ["y" => 2, "x" => 1];
var_dump($a == $b);
var_dump($a === $b);
var_dump([] === []);
// bool(true)
// bool(false)
// bool(true)
Comparar con [] es una forma clara de saber si un array está vacío: if ($errores === []).
Errores frecuentes
- Empezar a contar en 1: el primer elemento es
$lista[0]y el último$lista[count($lista) - 1]. - Usar
echocon un array: muestraArrayy un aviso. Usaprint_r(),var_dump()oimplode(). - Leer claves sin comprobar que existen: da Undefined array key. Usa
??oisset(). - Olvidar las comillas en claves de texto:
$socio[nombre]es un error en PHP 8; escribe$socio["nombre"]o$socio['nombre']. - Esperar que
unset()renumere los índices: deja huecos. Usaarray_values()si los necesitas seguidos. - Usar
in_array()sin el tercer argumentotrue: compara con==y puede dar coincidencias falsas. - Confundir
$lista[] = xcon$lista = x: el primero añade un elemento; el segundo sustituye todo el array por un valor.
Resumen
| Tarea | Sintaxis |
|---|---|
| Crear una lista | $a = ["x", "y", "z"]; |
| Crear un asociativo | $a = ["clave" => "valor"]; |
| Leer | $a[0], $a["clave"] |
| Añadir al final | $a[] = valor; |
| Modificar / añadir clave | $a["clave"] = valor; |
| Número de elementos | count($a) |
| Inspeccionar | print_r($a), var_dump($a) |
| Valor por defecto | $a["clave"] ?? "defecto" |
| ¿Existe la clave? | isset($a["k"]), array_key_exists("k", $a) |
| ¿Está el valor? | in_array($v, $a, true) |
| Borrar | unset($a["k"]); y array_values($a) para renumerar |
| Multidimensional | $a[1]["campo"] |
| Desestructurar | [$x, $y] = $a;, ["k" => $v] = $a; |
| Unir | [...$a, ...$b] |
En la siguiente lección conocerás las funciones que PHP trae para ordenar, filtrar y transformar arrays: funciones de arrays.
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.