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.

Notación compacta de matrices

En PHP 5.4 (publicado en marzo de 2012) se introdujo en PHP la notación compacta de matrices. 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.

Desde el curso 2017/18, en estos apuntes se utiliza la notación compacta en los ejemplos y soluciones de ejercicios, aunque los alumnos pueden utilizar la notación clásica si así lo desean.

Crear una matriz

En la notación compacta, las matrices se crean empleando corchetes ([]).

<?php
// Notación compacta
$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
// Notación compacta
$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 otros valores de índices, el primer término tiene el índice [0], el segundo tiene el índice [1], 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


Una vez creada la matriz, los elementos individuales se pueden utilizar como si fueran variables independientes. Pero 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 (undefined offset). Los avisos no interrumpen la ejecución del programa, pero se deben corregir porque el programa seguramente no tendrá el comportamiento esperado:

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

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

Notice: Undefined offset: 3 in ejemplo.php on line 4


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 = [];
?>

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

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

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

García

Matrices asociativas

Las matrices de PHP son matrices asociativas, es decir, que los índices no tienen por qué ser correlativos, ni siquiera tienen por qué ser números.

Al crear matrices asociativas, debemos indicar el valor de los índices, utilizando la notación $indice => $valor:

<?php
$cuadrados = [3 => 9, 5 => 25, 10 => 100];

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

El cuadrado de 3 es 9


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, pero los índices deben escribirse sin comillas, aunque sean cadenas.

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";
print "\n";
print "<p>Camilo tiene {$edades[Camilo]} años</p>\n";
?>
Notice: Use of undefined constant Bárbara - assumed 'Bárbara' in ejemplo.php on line 4

Bárbara tiene 19 años


Notice: Use of undefined constant Camilo - assumed 'Camilo' in ejemplo.php on line 6

Camilo tiene 17 años

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

Matrices multidimensionales

Las matrices pueden ser multidimensionales, es decir, matrices cuyos elementos son 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 no sustituye las referencias a valores de matrices de más de una dimensión dentro de las cadenas, por lo que se necesita o bien utilizar llaves, o bien concatenar cadenas y referencias a matrices. Como en el caso de las matrices de una dimensión, los índices que sean cadenas deben escribirse con comillas si la referencia está dentro de una cadena o entre llaves.

Incorrecto
<?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";
?>
Notice: Array to string conversion in ejemplo.php on line 6

Notice: 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

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.

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

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

print "{$datos}";
?>
Notice: 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

En la notación compacta, se pueden añadir elementos a una matriz indicando o no el índice del nuevo elemento:

Unión de 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.

Más información general sobre las matrices

Cada elemento de la matriz se comporta como una variable independiente y se pueden almacenar datos de tipos distintos en una misma matriz.

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


Los valores de los índices numéricos suelen ser siempre positivos, pero PHP también permite que sean negativos, aunque hay que tener cuidado al imprimirlos:

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

print "<p>$nombres[-3]<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 3
Correcto
<?php
$nombres[-3] = "Alba";

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

Alba

Alba

PHP no permite valores decimales en los índices numéricos. En caso de usarlos, PHP los trunca automáticamente a enteros (por lo que en general no se recomienda utilizarlos):

<?php
$nombres[1.7] = "Alba";

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

Alba

<?php
$nombres[1.7] = "Alba";

print "<p>" . $nombres[1.2] . "<p>\n";
?>

Alba

Como en el caso de los negativos, hay que tener cuidado al imprimirlos:

Incorrecto
<?php
$nombres[1.7] = "Alba";

print "<p>$nombres[1.7]<p>\n";
?>
Parse error: syntax error, unexpected '.', expecting ']' in ejemplo.php on line 3
Correcto
<?php
$nombres[1.7] = "Alba";

print "<p>{$nombres[1.2]}<p>\n";
print "\n";
print "<p>" . $nombres[1.2] . "<p>\n";
?>

Alba

Alba


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
        )

)

Borrar una matriz o elementos de una matriz

La función unset() permite borrar una matriz o elementos de una matriz.

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

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

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";

unset($matriz);

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

Notice:  Undefined variable: matriz in prueba.php on line 8

Si se intenta borrar un elemento no definido, PHP no genera ningún aviso.

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

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

unset($matriz[3]);

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

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
)