Matrices

En esta lección se comentan los aspectos generales de las matrices en PHP. Las funciones específicas para trabajar con matrices se comentan en la lección Funciones de matrices.

Qué es una matriz

Una matriz es un tipo de variable que permite almacenar simultáneamente varios datos diferentes, a los que se accede mediante un índice, numérico o de texto. En inglés, las matrices se llaman arrays. A veces el término inglés array se traduce como arreglo.

En PHP, una matriz es un tipo de variable muy flexible, ya que podemos añadir, modificar, eliminar o reordenar los elementos de forma individual. Además los elementos pueden ser de tipos de datos diferentes.

Si los elementos de una matriz son datos de tipos simples (booleanos, enteros, decimales o cadenas), sólo se necesita un índice para identificar los datos. Se dice entonces que las matrices son unidimensionales. A las matrices de una dimensión también se les llama vectores.

Si los elementos de una matriz son a su vez también matrices, se necesitan varios índices para identificar a los datos. Se dice entonces que las matrices son multidimensionales.

Crear una matriz

Las matrices se definen mediante corchetes ([]).

<?php
$nombres = ["Ana", "Bernardo", "Carmen"];
?>

Los elementos de la matriz deben separarse con comas. Tras el último elemento se puede escribir o no una coma, pero la coma final no crea un nuevo elemento (la matriz obtenida es la misma, independientemente de que se escriba la coma final o no).

<?php
$nombres = ["Ana", "Bernardo", "Carmen", ];
?>

Para hacer referencia a los valores individuales de la matriz, se deben utilizar índices, que se escriben entre corchetes ([ ]). Si al crear la matriz no se han indicado los valores de índices, PHP asigna al primer término el índice [0], el índice [1] al segundo, etc.:

PHP sustituye las referencias a valores de matrices de una dimensión dentro de las cadenas, por lo que no es necesario concatenar cadenas y referencias a matrices.

<?php
$nombres = ["Ana", "Bernardo", "Carmen"];

print "<p>$nombres[1]</p>\n";
print "<p>$nombres[0]</p>\n";
?>

Bernardo

Ana


También se pueden crear matrices asignando directamente un elemento de la matriz.

<?php
$apellidos[0] = "García";

print "<p>$apellidos[0]</p>\n";
?>

García


Una matriz puede almacenar datos de tipos distintos.

<?php
$datos = ["Santiago", "Ramón y Cajal", 1852];

print "<p>$datos[0] $datos[1] nació en $datos[2].<p>\n";
?>

Santiago Ramón y Cajal nació en 1852.


Una vez creada la matriz, los elementos individuales se pueden utilizar en el programa como cualquier otra variable. Para referirse a un elemento individual, hay que indicar siempre el índice correspondiente.

<?php
$nombres = ["Ana", "Bernardo", "Carmen"];

print "<p>$nombres[1]</p>\n";

$nombres[1] = "David";

print "<p>$nombres[1]</p>\n";
?>

Bernardo

David


Si se solicita un valor no definido de una matriz, se produce un aviso. Los avisos no interrumpen la ejecución del programa, pero se deben corregir porque el programa seguramente no tendrá el comportamiento esperado:

Desaconsejado
<?php
$nombres = ["Ana", "Bernardo", "Carmen"];

print "<p>Nombre: $nombres[3]<p>\n";
?>

Warning: Undefined array key 3 in ejemplo.php on line 4

Nombre:


Se puede crear una matriz vacía (para añadirle posteriormente elementos). Se suele hacer para asegurarse de que una matriz ya utilizada en el programa no contiene elementos o para evitar errores si las operaciones que se van a realizar posteriormente requieren la existencia de la matriz (por ejemplo, si se van a utilizar uniones de matrices).

<?php
$nombres = [];
?>

Matrices asociativas

En PHP, los índices de las matrices pueden ser números enteros o cadenas. Este tipo de matrices se denominan matrices asociativas, ya que las matrices no son colecciones ordenadas de elementos a los que se acceden mediante números positivos correlativos, sino conjuntos de valores que se identifican mediante etiquetas.

Podemos crear una matriz asociativa indicando el valor de los índices o utilizando la notación $indice => $valor:

<?php
// Matriz definida elemento a elemento
$cuadrados[3] = 9;
$cuadrados[5] = 25;
$cuadrados[10] = 100;
// Matriz definida con la notación =>
$cuadrados = [3 => 9, 5 => 25, 10 => 100];

print "<p>El cuadrado de 3 es $cuadrados[3]</p>\n";
?>

El cuadrado de 3 es 9

En una matriz asociativa, los índices pueden ser números enteros (positivos o negativos) o cadenas:

<?php
// Matriz definida elemento a elemento
$matriz[10] = "diez";
$matriz[-1] = "menos uno";
$matriz["uno"] = 1;
$matriz["ciento veinte"] = 120;
// Matriz definida con la notación =>
$matriz = [10 => "diez", -1 => "menos uno", "uno" => 1, "ciento veinte" => 120];
?>

Si utilizando la notación $indice => $valor se repite algún índice, el valor que se guarda en la matriz es únicamente el último.

<?php
$matriz = [1 => 10, 1 => 20, 1 => 30];
print "<p>$matriz[1]</p>\n";
?>

30


PHP sustituye las referencias a valores de matrices de una dimensión dentro de las cadenas, por lo que no es necesario concatenar cadenas y referencias a matrices de una dimensión.

Correcto
<?php
$nombres = ["Andrés", "Bárbara", "Camilo"];

print "<p>Ella se llama $nombres[1]</p>\n";
?>

Ella se llama Bárbara

Si los índices no son numéricos, sino cadenas, los índices deben escribirse sin comillas.

Incorrecto
<?php
$edades = ["Andrés" => 20, "Bárbara" => 19, "Camilo" => 17];

print "<p>Bárbara tiene $edades["Bárbara"] años</p>\n";
?>
Parse error: syntax error, unexpected '"', expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in ejemplo.php on line 4
Correcto
<?php
$edades = ["Andrés" => 20, "Bárbara" => 19, "Camilo" => 17];

print "<p>Bárbara tiene $edades[Bárbara] años</p>\n";
?>

Bárbara tiene 19 años

Si la referencia a un valor de una matriz está fuera de una cadena o entre llaves, los índices que son cadenas deben escribirse con comillas.

Incorrecto
<?php
$edades = ["Andrés" => 20, "Bárbara" => 19, "Camilo" => 17];

print "<p>Bárbara tiene " . $edades[Bárbara] . " años</p>\n";
?>
Fatal error: Uncaught Error: Undefined constant "Bárbara" in ejemplo.php:4 Stack trace #0 {main} thrown in ejemplo on line 4
Incorrecto
<?php
$edades = ["Andrés" => 20, "Bárbara" => 19, "Camilo" => 17];

print "<p>Camilo tiene {$edades[Camilo]} años</p>\n";
?>
Fatal error: Uncaught Error: Undefined constant "Camilo" in ejemplo.php:4 Stack trace #0 {main} thrown in ejemplo on line 4
Correcto
<?php
$edades = ["Andrés" => 20, "Bárbara" => 19, "Camilo" => 17];

print "<p>Bárbara tiene " . $edades["Bárbara"] . " años</p>\n";
print "\n";
print "<p>Camilo tiene {$edades["Camilo"]} años</p>\n";
?>

Bárbara tiene 19 años

Camilo tiene 17 años


Los valores de los índices numéricos suelen ser siempre positivos, pero PHP también permite que sean negativos:

<?php
$nombres[-3] = "Alba";

print "<p>$nombres[-3]<p>\n";
?>

Alba


PHP no permite valores decimales en los índices numéricos, aunque se pueden escribir decimales en los índices porque PHP los trunca automáticamente a enteros y trabaja con los valores enteros. Pese a ello, se recomienda NO utilizar nunca decimales en los índices numéricos. De hecho, a partir de PHP 8.1, si la conversión de enteros a decimales supone una pérdida de precisión se genera un error E_DEPRECATED, como se comenta en la lección Cambios en el lenguaje.

Matrices multidimensionales

Las matrices pueden ser multidimensionales, es decir, una matriz puede tener elementos que sean a su vez matrices. Para referirse a los elementos concretos, se necesitan utilizar varios índices (tantos como dimensiones -niveles de anidamiento- tenga la matriz).

<?php
// Definiciones equivalentes de una mismsa matriz
// En una sola línea:
$matriz = [[20, 30, 40], [100, 200, 300]];
// En varias líneas para facilitar la lectura:
$matriz = [
  [20, 30, 40],
  [100, 200, 300]
];
// Definiendo los elementos de primer nivel:
$matriz[0] = [20, 30, 40];
$matriz[1] = [100, 200, 300];
// Definiendo los elementos de segundo nivel:
$matriz[0][0] = 20;
$matriz[0][1] = 30;
$matriz[0][2] = 40;
$matriz[1][0] = 100;
$matriz[1][1] = 200;
$matriz[1][2] = 300;
?>

Las matrices multidimensionales siguen siendo asociativas, es decir, cada índice puede ser un número entero o una cadena. Además, el número de elementos de cada submatriz puede ser distinto, y los índices de las submatrices pueden repetirse en elementos distintos.


Desaconsejado
<?php
$datos = [
    ["nombre" => "pepe", "edad" => 25, "peso" => 80],
    ["nombre" => "juan", "edad" => 22, "peso" => 75]
];

print "<p>$datos[0][nombre] tiene $datos[0][edad] años.</p>\n";
?>
Warning: Array to string conversion in ejemplo.php on line 6

Warning: Array to string conversion in ejemplo.php on line 6

Array[nombre] tiene Array[edad] años.

Correcto
<?php
$datos = [
    ["nombre" => "pepe", "edad" => 25, "peso" => 80],
    ["nombre" => "juan", "edad" => 22, "peso" => 75]
];

print "<p>{$datos[1]["nombre"]} pesa {$datos[1]["peso"]} kilos</p>\n";
print "\n";
print "<p>" . $datos[0]["nombre"] . " tiene " . $datos[0]["edad"] . " años</p>\n";
?>

pepe tiene 25 años

juan pesa 75 kilos


En el caso de las matrices multidimensionales, la misma información se puede guardar de varias formas distintas. Por ejemplo, la matriz siguiente guarda información sobre la edad y el peso de varias personas:

<?php
$datos["pepe"]["edad"] = 25;
$datos["pepe"]["peso"] = 80;
$datos["juan"]["edad"] = 22;
$datos["juan"]["peso"] = 75;

print "<pre>\n"; print_r($datos); print "</pre>\n";
?>
Array
(
    [pepe] => Array
        (
            [edad] => 25
            [peso] => 80
        )

    [juan] => Array
        (
            [edad] => 22
            [peso] => 75
        )

)

En el ejemplo anterior se ha utilizado el nombre de la persona como índice de la matriz, lo que no es una buena idea, ya que no podríamos guardar los datos de dos personas con el mismo nombre. Sería mejor guardar la información de manera similar a como se guardaría en una base de datos. Una matriz de dos dimensiones sería en ese caso el equivalente a una tabla, el primer índice correspondería al número de registro y el segundo índice iría tomando los valores de los campos de la tabla (nombre, edad, peso, etc).

<?php
$datos[0]["nombre"] = "pepe";
$datos[0]["edad"] = 25;
$datos[0]["peso"] = 80;
$datos[1]["nombre"] = "juan";
$datos[1]["edad"] = 22;
$datos[1]["peso"] = 75;

print "<pre>\n"; print_r($datos); print "</pre>\n";
?>
Array
(
    [0] => Array
        (
            [nombre] => pepe
            [edad] => 25
            [peso] => 80
        )

    [1] => Array
        (
            [nombre] => juan
            [edad] => 22
            [peso] => 75
        )

)

Imprimir todos los valores de una matriz: la función print_r()

La instrucción print permite imprimir valores individuales de una matriz, pero no matrices completas.

Desaconsejado
<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "Datos: $datos";
?>
Warning: Array to string conversion in ejemplo.php on line 5
Array
Desaconsejado
<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "Datos: {$datos}";
?>
Warning: Array to string conversion in ejemplo.php on line 5
Array

La función print_r($variable [, $devolver]) permite imprimir todos los valores de una matriz de forma estructurada. En general, print_r() imprime cualquier variable compuesta de forma legible.

Esta función no se suele utilizar en programas definitivos, pero puede ser útil mientras estamos elaborando un programa, por ejemplo para comprobar en un punto del programa si la matriz contiene los valores esperados. Una vez comprobado, la instrucción se puede comentar o borrar.


Aunque print_r() genera espacios y saltos de línea en el código fuente de la página para indicar el anidamiento, print_r() no genera etiquetas html, por lo que el navegador no muestra esos espacios y saltos de línea.

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print_r($datos);
?>
Array ( [nombre] => Santiago [apellidos] => Ramón y Cajal )

Para mejorar la legibilidad una solución es añadir la etiqueta <pre>, que fuerza al navegador a mostrar los espacios y saltos de línea.

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "<pre>";
print_r($datos);
print "</pre>";
?>
Array
(
[nombre] => Santiago
[apellidos] => Ramón y Cajal
)
<?php
$datos[1]["nombre"] = "Santiago";
$datos[1]["apellidos"] = "Ramón y Cajal";
$datos[2]["nombre"] = "Leonardo";
$datos[2]["apellidos"] = "Torres Quevedo";

print "<pre>";
print_r($datos);
print "</pre>";
?>
Array
(
[1] => Array
    (
        [nombre] => Santiago
        [apellidos] => Ramón y Cajal
    )

[2] => Array
    (
        [nombre] => Leonardo
        [apellidos] => Torres Quevedo
    )
)

Si se añade un segundo argumento con el valor true, print_r() no imprime nada pero devuelve el texto que se imprimiría si no estuviera el argumento true. Se utiliza para concatenar la respuesta de la función o para guardarla en una variable que se puede imprimir posteriormente

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

$tmp = print_r($datos, true);
print "<p>La matriz es $tmp</p>\n";
?>

La matriz es Array ( [nombre] => Santiago [apellidos] => Ramón y Cajal )

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "<p>La matriz es " . print_r($datos, true) . "</p>\n";
?>

La matriz es Array ( [nombre] => Santiago [apellidos] => Ramón y Cajal )

Añadir elementos a una matriz

Se pueden añadir elementos a una matriz indicando o no el índice del nuevo elemento:


Los siguientes ejemplos que crean una matriz con tres valores numéricos del 1 al 6 son prácticamente equivalentes:

<?php
$dados = [];
for ($i = 0; $i < 3; $i++) {
    $dados[$i] = rand(1, 6);
}

print"<pre>"; print_r($dados); print"</pre>\n";
?>
Array
(
    [0] => 2
    [1] => 4
    [2] => 6
)
        
<?php
for ($i = 0; $i < 3; $i++) {
    $dados[] = rand(1, 6);
}

print"<pre>"; print_r($dados); print"</pre>\n";
?>
Array
(
    [0] => 6
    [1] => 3
    [2] => 3
)
        

La diferencia es que en el primer caso nos aseguramos de que la matriz no contenga valores (al igualarla a una matriz vacía) y cuáles son los índices de los elementos creados (0, 1 y 2). En el segundo caso damos por supuesto que la matriz no contiene valores y que al añadir valores a una matriz vacía PHP les dará 0, 1, 2 etc. como índice. En caso de que no sea así nos podemos encontrar con sorpresas.

Si repetimos en el mismo programa estos ejemplos de código, el resultado final no es el mismo:

<?php
$dados = [];
for ($i = 0; $i < 3; $i++) {
    $dados[$i] = rand(1, 6);
}

print"<pre>"; print_r($dados); print"</pre>\n";

$dados = [];
for ($i = 0; $i < 3; $i++) {
    $dados[$i] = rand(1, 6);
}

print"<pre>"; print_r($dados); print"</pre>\n";
?>
Array
(
    [0] => 4
    [1] => 2
    [2] => 1
)
        
Array
(
    [0] => 4
    [1] => 5
    [2] => 2
)
        
<?php
for ($i = 0; $i < 3; $i++) {
    $dados[] = rand(1, 6);
}

print"<pre>"; print_r($dados); print"</pre>\n";

for ($i = 0; $i < 3; $i++) {
  $dados[] = rand(1, 6);
}

print"<pre>"; print_r($dados); print"</pre>\n";
?>
Array
(
    [0] => 1
    [1] => 4
    [2] => 4
)
        
Array
(
    [0] => 1
    [1] => 4
    [2] => 4
    [3] => 6
    [4] => 3
    [5] => 2
)
        

En el segundo ejemplo, la segunda vez que añadimos elementos a la matriz, estos se añaden a los ya existentes.

Borrar una matriz o elementos de una matriz

En general, la función unset() permite borrar variables. En el caso de las matrices, unset() permite borrar tanto la matriz completa como elementos de la matriz.

<?php
$matriz = [5 => 25, -1 => "negativo", "número 1" => "cinco"];

print "<pre>\n"; print_r($matriz); print "</pre>\n";

// Borramos un elemento de la matriz
unset($matriz[5]);

print "<pre>\n"; print_r($matriz); print "</pre>\n";
?>
Array
(
    [5] => 25
    [-1] => negativo
    [número 1] => cinco
)

Array
(
    [-1] => negativo
    [número 1] => cinco
)
<?php
$matriz = [5 => 25, -1 => "negativo", "número 1" => "cinco"];

print "<pre>\n"; print_r($matriz); print "</pre>\n";

// Borramos la matriz completa
unset($matriz);

print "<pre>\n"; print_r($matriz); print "</pre>\n";
?>
Array
(
    [5] => 25
    [-1] => negativo
    [número 1] => cinco
)

Warning:  Undefined variable $matriz in prueba.php on line 8

La función unset() permite borrar varias variables a la vez, escribiendo los nombres de las variables como argumentos (separadas por comas).

<?php
$matriz = [5 => 25, -1 => "negativo", "número 1" => "cinco"];

print "<pre>\n"; print_r($matriz); print "</pre>\n";

// Borramos dos elementos de la matriz de una vez
unset($matriz[5], $matriz["número 1"]);

print "<pre>\n"; print_r($matriz); print "</pre>\n";
?>
Array
(
    [5] => 25
    [-1] => negativo
    [número 1] => cinco
)

Array
(
    [-1] => negativo
)

Si se borra un elemento que no estaba definido, PHP no genera ningún aviso.

<?php
$nombres = ["Alba", "Bernardo"];

print "<pre>\n"; print_r($nombres); print "</pre>\n";

// "Borrramos" un elemento que no existe
unset($matriz[3]);

print "<pre>\n"; print_r($nombres); print "</pre>\n";
?>
Array
(
    [0] => Alba
    [1] => Bernardo
)

Array
(
    [0] => Alba
    [1] => Bernardo
)

También se pueden borrar todos los elementos de una matriz sin borrar la propia matriz asignando la matriz vacía ([]):

<?php
$matriz = [5 => 25, -1 => "negativo", "número 1" => "cinco"];

print "<pre>\n"; print_r($matriz); print "</pre>\n";

$matriz = [];

print "<pre>\n"; print_r($matriz); print "</pre>\n";
?>
Array
(
    [5] => 25
    [-1] => negativo
    [número 1] => cinco
)

Array
(
)

Copiar una matriz

Se puede copiar una matriz creando una nueva variable. Las dos matrices son independientes, por lo que modificar posteriormente una de ellas no afecta a la otra.

<?php
$cuadrados = [5 => 25, 9 => 81];

$cuadradosCopia = $cuadrados;

$cuadrados[] = 100;

print "<p>Matriz inicial (modificada):</p>\n";
print "<pre>\n"; print_r($cuadrados); print "</pre>\n";
print "\n";

print "<p>Copia de la matriz inicial (sin modificar):</p>\n";
print "<pre>\n"; print_r($cuadradosCopia); print "</pre>\n";
?>

Matriz inicial (modificada):

Array
(
    [5] => 25
    [9] => 81
    [10] => 100
)

Copia de la matriz inicial (sin modificar):

Array
(
    [5] => 25
    [9] => 81
)

Unir matrices

Los operadores + (suma) += (suma combinada) realizan la unión de dos matrices. La unión de dos matrices contiene todos los elementos de la primera matriz y únicamente los elementos de la segunda matriz cuyo índice no se encuentra en la primera matriz.

Notación clásica de matrices

En PHP 5.4 (publicado en marzo de 2012) se introdujo en PHP la notación compacta de matrices, que es la que se explica en esta lección y se utiliza en estos apuntes desde el curso 2017/18. Como se explica en la lección Notación clásica de matrices, la diferencia entre ambas notaciones reside en la manera de definir matrices o de añadir valores a una matriz.