Desestructuración de arrays en PHP: list(), [] y asignación múltiple

La desestructuración de arrays en PHP permite asignar varios elementos a variables independientes en una sola línea. PHP tiene dos sintaxis para esto: la función list(), disponible desde PHP 5, y los corchetes [], introducidos en PHP 7.1. Ambas hacen lo mismo; los corchetes son la forma moderna preferida.

Sintaxis básica con list() y []

<?php
$coordenadas = [40.416775, -3.703790, 654];

// Con list() — sintaxis clásica
list($latitud, $longitud, $altitud) = $coordenadas;

// Con [] — sintaxis moderna y equivalente
[$latitud, $longitud, $altitud] = $coordenadas;

echo $latitud;   // 40.416775
echo $longitud;  // -3.703790

// Ignorar elementos con posición vacía
[, $longitud, $altitud] = $coordenadas;  // ignoramos latitud
echo $longitud;  // -3.703790

Desestructurar el resultado de una consulta SQL

Uno de los usos más comunes: asignar los campos de una fila de base de datos a variables con nombre legible:

<?php
$fila = $pdo->query("SELECT nombre, email, rol FROM usuarios WHERE id = 1")
             ->fetch(PDO::FETCH_NUM);

[$nombre, $email, $rol] = $fila;
echo "Bienvenido, $nombre ($rol)";

// Con FETCH_ASSOC — desestructuración por clave (PHP 7.1+)
$fila = $pdo->query("SELECT nombre, email FROM usuarios WHERE id = 1")
             ->fetch(PDO::FETCH_ASSOC);

['nombre' => $nombre, 'email' => $email] = $fila;
// Las claves no tienen que estar en el mismo orden que en el array

Parsear líneas de CSV

<?php
$linea = 'Ana García,[email protected],Barcelona,28';
[$nombre, $email, $ciudad, $edad] = str_getcsv($linea);
echo "$nombre vive en $ciudad y tiene $edad años";

// Procesando un archivo CSV completo
$handle = fopen('clientes.csv', 'r');
$cabecera = fgetcsv($handle);  // primera línea ignorada
while ($fila = fgetcsv($handle)) {
    [$id, $nombre, $email, $saldo] = $fila;
    // ... procesar
}
fclose($handle);

Swap de variables sin variable temporal

El truco clásico para intercambiar dos variables sin necesitar una tercera:

<?php
$a = 'primero';
$b = 'segundo';

// Forma clásica (necesita variable temporal):
$tmp = $a;
$a = $b;
$b = $tmp;

// Con desestructuración (más conciso):
[$a, $b] = [$b, $a];
echo $a;  // segundo
echo $b;  // primero

// Útil en algoritmos de ordenación:
function bubble_sort(array &$arr): void {
    $n = count($arr);
    for ($i = 0; $i < $n - 1; $i++) {
        for ($j = 0; $j < $n - $i - 1; $j++) {
            if ($arr[$j] > $arr[$j + 1]) {
                [$arr[$j], $arr[$j + 1]] = [$arr[$j + 1], $arr[$j]];
            }
        }
    }
}

Desestructuración en foreach

Se puede usar directamente en el foreach para arrays de arrays:

<?php
$productos = [
    [1, 'Teclado', 49.99],
    [2, 'Ratón',   29.99],
    [3, 'Monitor', 299.00],
];

foreach ($productos as [$id, $nombre, $precio]) {
    echo "$id: $nombre — {$precio}€n";
}

// Con arrays asociativos en foreach (PHP 7.1+)
$usuarios = [
    ['nombre' => 'Ana', 'rol' => 'admin'],
    ['nombre' => 'Luis', 'rol' => 'editor'],
];

foreach ($usuarios as ['nombre' => $nombre, 'rol' => $rol]) {
    echo "$nombre es $roln";
}

Arrays anidados

La desestructuración puede ser multinivel:

<?php
$punto3D = [[1, 2], 3];
[[$x, $y], $z] = $punto3D;
echo "$x, $y, $z";  // 1, 2, 3

// Respuesta de una API anidada
$respuesta = [
    'status' => 'ok',
    'data'   => ['id' => 42, 'nombre' => 'Ana'],
];
['data' => ['id' => $id, 'nombre' => $nombre]] = $respuesta;
echo "$id: $nombre";  // 42: Ana

El error típico con array_filter

Después de array_filter(), las claves originales se preservan. Si intentas desestructurar por posición, el resultado puede ser inesperado:

<?php
$arr = [0, 1, 2, 3, 4];
$filtrado = array_filter($arr, fn($v) => $v > 2);
// $filtrado = [3 => 3, 4 => 4]  — claves 3 y 4, no 0 y 1

[$a, $b] = $filtrado;
// PHP busca los índices 0 y 1, que no existen
// $a = null, $b = null  — ¡silencioso y confuso!

// Solución: reindexar con array_values()
[$a, $b] = array_values($filtrado);
echo $a;  // 3
echo $b;  // 4

Desestructuración con valores por defecto

PHP no tiene sintaxis nativa de "valor por defecto al desestructurar", pero puedes simularlo:

<?php
function desestructurar(array $arr, mixed ...$defaults): array {
    return array_replace(array_fill(0, count($defaults), null), $arr) + $defaults;
}

// O más simple con el operador de coalescencia nula:
$datos = ['Ana', 'Barcelona'];  // sin tercer elemento
[$nombre, $ciudad, $rol] = $datos + [2 => 'usuario'];
echo $rol;  // usuario

// O directamente
$nombre = $datos[0] ?? 'Anónimo';
$ciudad = $datos[1] ?? 'Desconocida';
$rol    = $datos[2] ?? 'usuario';

Retornar múltiples valores desde una función

PHP no tiene retorno múltiple nativo como Go o Python, pero la desestructuración lo simula perfectamente:

<?php
function dividir(int $dividendo, int $divisor): array {
    if ($divisor === 0) {
        throw new DivisionByZeroError();
    }
    return [intdiv($dividendo, $divisor), $dividendo % $divisor];
}

[$cociente, $resto] = dividir(17, 5);
echo "17 / 5 = $cociente con resto $resto";  // 3 con resto 2

// minmax en una sola llamada
function minmax(array $arr): array {
    return [min($arr), max($arr)];
}
[$min, $max] = minmax([3, 1, 7, 2, 9]);

La desestructuración con [] es una de las mejoras más prácticas de PHP 7.1. Reduce el código de asignación, hace los foreach más legibles y permite el intercambio de variables en una línea. El único punto a recordar: cuando trabajes con arrays filtrados o de claves no secuenciales, array_values() es tu aliado para evitar asignaciones nulas silenciosas.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP