PHP Desestruturação (list)

Muitas vezes você tem um array e quer seus itens em variáveis separadas: o dia, o mês e o ano de uma data; o nome e a nota de um aluno. Em vez de escrever uma linha para cada item, o PHP deixa você "desmontar" o array numa linha só. Isso se chama desestruturação (destructuring): você desfaz a estrutura do array e espalha os valores em variáveis. No final da aula, você vê o caminho inverso, o spread ..., que espalha um array dentro de outro.

Você vai aprender
  • A forma curta [$a, $b] = $array; e a antiga list($a, $b) = $array;.
  • O que acontece com itens a mais ou a menos, e como pular itens.
  • Desestruturar pelas chaves: ["nome" => $nome] = $aluna;.
  • Trocar o valor de duas variáveis numa linha.
  • Desestruturar direto no foreach.
  • Juntar arrays com o spread: [...$a, ...$b].

A ideia: desembalar a compra

Pense numa sacola de compras com três itens. Você pode tirar um de cada vez ("pego o primeiro e ponho na geladeira; pego o segundo e ponho no armário…") ou virar a sacola de uma vez sobre a mesa, com cada item caindo num lugar já combinado. A desestruturação é o segundo jeito: você diz de antemão "o primeiro vai para $dia, o segundo para $mes, o terceiro para $ano".

[$a, $b] = … e list()

<?php
$data = [16, 10, 2026];

// um por um
$dia = $data[0];
$mes = $data[1];
$ano = $data[2];
echo "$dia/$mes/$ano\n";

// desestruturando
[$dia, $mes, $ano] = $data;
echo "$dia/$mes/$ano\n";

// a forma antiga
list($d, $m, $a) = $data;
echo "$d/$m/$a\n";
[$dia, $mes, $ano]
Do lado esquerdo do =, colchetes com variáveis não criam um array: eles dizem "receba os itens nestas variáveis", na ordem.
=
A atribuição de sempre.
$data
O array que será desmontado. O item de índice 0 vai para a primeira variável, o 1 para a segunda, e assim por diante.
list($d, $m, $a)
A mesma coisa, com a palavra list ("lista"). Existe desde sempre; a forma com colchetes chegou no PHP 7.1.
$ php d-basico.php
16/10/2026
16/10/2026
16/10/2026

Os três jeitos dão o mesmo resultado. list() e [ ] são equivalentes; o código moderno usa os colchetes, mas você vai encontrar list() em muito código e tutorial.

O uso mais comum: com explode

Desestruturação brilha quando um texto é cortado em partes. A função explode ("explodir") corta um texto num separador e devolve um array (aula Funções de String):

<?php
[$dia, $mes, $ano] = explode("/", "16/10/2026");
var_dump($dia, $mes, $ano);
[$nome, $email] = explode(";", "Ana;ana@exemplo.com");
echo "Nome: $nome | E-mail: $email\n";
$ php d-explode.php
string(2) "16"
string(2) "10"             « vieram como texto: o explode sempre devolve strings
string(4) "2026"
Nome: Ana | E-mail: ana@exemplo.com

Itens a mais e a menos

<?php
[$primeiro, $segundo] = ["Ana", "Bruno", "Carla"];
echo "$primeiro e $segundo\n";
[$a, $b, $c] = ["Ana", "Bruno"];
var_dump($c);
$ php d-qtd.php
Ana e Bruno             « a Carla sobrou e foi ignorada, sem aviso

Warning: Undefined array key 2 in /home/ana/site/d-qtd.php on line 4
NULL                    « faltou item para $c: aviso, e $c fica null

Itens sobrando: tudo bem. Variáveis sobrando: o mesmo aviso que você já conhece de Arrays Indexados, porque, por baixo, [$a, $b, $c] = $x é o mesmo que ler $x[0], $x[1] e $x[2].

Pular itens

Deixe o lugar vazio entre as vírgulas para ignorar um item:

<?php
$linha = ["Ana", 29, "Recife", 9.5];
[$nome, , $cidade] = $linha;       // pula a idade
echo "$nome mora em $cidade\n";
[, , , $nota] = $linha;            // pula os três primeiros
echo "Nota: $nota\n";
$ php d-pular.php
Ana mora em Recife
Nota: 9.5

Funciona, mas [, , , $nota] é difícil de ler. Quando os itens têm nomes, a próxima forma é bem melhor.


Com chaves: ["nome" => $nome] = …

Com arrays associativos, você diz qual chave vai para qual variável. A ordem deixa de importar, e você pega só o que precisa.

<?php
$aluna = ["nome" => "Ana", "idade" => 29, "cidade" => "Recife", "nota" => 9.5];
["nome" => $nome, "nota" => $nota] = $aluna;
echo "$nome tirou $nota\n";
["cidade" => $c, "nome" => $n] = $aluna;
echo "$n, de $c\n";
list("idade" => $idade) = $aluna;
echo "Idade: $idade\n";
["email" => $email] = $aluna;
var_dump($email);
"nome" => $nome
"O valor da chave "nome" vai para a variável $nome". É a mesma seta da criação do array, mas aqui o lado direito é uma variável que vai receber o valor.
"cidade" => $c, "nome" => $n
A ordem é livre, e o nome da variável não precisa ser igual ao da chave.
$ php d-chaves.php
Ana tirou 9.5
Ana, de Recife
Idade: 29

Warning: Undefined array key "email" in /home/ana/site/d-chaves.php on line 9
NULL

Pegue outros campos da ficha (a idade, a nota) com a forma de chaves, e experimente trocar dois valores com [$x, $y] = [$y, $x].

<?php
$aluna = ["nome" => "Ana", "idade" => 29, "cidade" => "Recife", "nota" => 9.5];

["nome" => $nome, "cidade" => $cidade] = $aluna;
echo "$nome mora em $cidade\n";

$primeiro = "Ana";
$segundo = "Bruno";
[$primeiro, $segundo] = [$segundo, $primeiro];
echo "Agora o primeiro é $primeiro\n";

Trocar o valor de duas variáveis

Um truque clássico. Para trocar o conteúdo de duas variáveis, o jeito tradicional precisa de uma terceira, temporária (como trocar o líquido de dois copos: você precisa de um copo vazio). Com desestruturação, é uma linha:

<?php
$a = "café";
$b = "leite";
[$a, $b] = [$b, $a];
echo "a = $a, b = $b\n";

// o jeito tradicional, com uma variável temporária
$x = 1;
$y = 2;
$temp = $x;
$x = $y;
$y = $temp;
echo "x = $x, y = $y\n";
$ php d-troca.php
a = leite, b = café
x = 2, y = 1

Como funciona: o lado direito, [$b, $a], cria primeiro um array novo com os valores atuais (["leite", "café"]); só depois esse array é desmontado em $a e $b.


No foreach

A desestruturação também funciona na variável do foreach. Com a tabela de alunos, o laço fica mais limpo: em vez de $aluno["nome"], você já recebe $nome.

<?php
$alunos = [
    ["nome" => "Ana",   "cidade" => "Recife", "nota" => 9.5],
    ["nome" => "Bruno", "cidade" => "Olinda", "nota" => 7.0],
];
foreach ($alunos as ["nome" => $nome, "nota" => $nota]) {
    echo "$nome: $nota\n";
}
$pontos = [[0, 0], [3, 4], [6, 8]];
foreach ($pontos as [$x, $y]) {
    echo "($x, $y)\n";
}
$entregas = ["Ana" => ["Recife", 2], "Bruno" => ["Olinda", 5]];
foreach ($entregas as $cliente => [$cidade, $dias]) {
    echo "$cliente: $cidade em $dias dias\n";
}
$ php d-foreach.php
Ana: 9.5
Bruno: 7
(0, 0)
(3, 4)
(6, 8)
Ana: Recife em 2 dias
Bruno: Olinda em 5 dias
LaçoA cada volta
foreach ($alunos as ["nome" => $nome, "nota" => $nota])Cada ficha é desmontada pelas chaves
foreach ($pontos as [$x, $y])Cada par [x, y] é desmontado pela posição
foreach ($entregas as $cliente => [$cidade, $dias])A chave vai para $cliente, e o valor (um array) é desmontado

Arrays dentro de arrays

Dá para desmontar vários níveis de uma vez, repetindo o formato do array:

<?php
$pedido = ["Ana", ["café", 2], ["pão", 10]];
[$cliente, [$produto1, $qtd1], [$produto2, $qtd2]] = $pedido;
echo "$cliente pediu $qtd1 $produto1 e $qtd2 $produto2\n";

$aluna = ["nome" => "Ana", "notas" => [9.0, 8.5, 10.0]];
["nome" => $nome, "notas" => [$n1, $n2]] = $aluna;
echo "$nome: $n1 e $n2\n";
$ php d-aninhado.php
Ana pediu 2 café e 10 pão
Ana: 9 e 8.5

Use com moderação: dois níveis ainda se leem bem; mais que isso, prefira desmontar em etapas.


O caminho inverso: o spread ...

A desestruturação tira os itens de dentro de um array. O spread (espalhar), escrito com três pontos ... antes de um array, faz o contrário: despeja os itens de um array dentro de outro que está sendo criado.

<?php
$manha = ["Ana", "Bruno"];
$noite = ["Carla", "Diego"];
$todos = [...$manha, ...$noite];
print_r($todos);
$comExtra = ["Zeca", ...$manha, "Elisa"];
echo implode(", ", $comExtra), "\n";

$padrao  = ["cor" => "azul", "tamanho" => "M"];
$escolha = ["cor" => "verde"];
print_r([...$padrao, ...$escolha]);
print_r([...$padrao, "fonte" => "Arial", "cor" => "rosa"]);

$numeros = [5 => "cinco", 9 => "nove"];
print_r([...$numeros]);
$ php d-spread.php
Array
(
    [0] => Ana
    [1] => Bruno
    [2] => Carla
    [3] => Diego
)
Zeca, Ana, Bruno, Elisa         « o spread pode ficar em qualquer posição
Array
(
    [cor] => verde              « chave repetida: vence a que vem depois
    [tamanho] => M
)
Array
(
    [cor] => rosa
    [tamanho] => M
    [fonte] => Arial
)
Array
(
    [0] => cinco                « chaves numéricas são renumeradas
    [1] => nove
)

O resultado é o mesmo do array_merge (veja Funções de Array): listas são emendadas e renumeradas, chaves de nome repetidas ficam com o último valor. A vantagem é poder misturar itens soltos e arrays na mesma expressão.

Spread em arraysDesde
Arrays com chaves numéricas (listas)PHP 7.4+
Arrays com chaves de nomePHP 8.1+ (antes, use array_merge)

Os mesmos três pontos aparecem em funções, para receber ou passar vários argumentos de uma vez (soma(...$numeros)). Isso é assunto de Funções Variádicas.


Quando dá errado

Warning: Undefined array key 2 na desestruturação
$ php d-qtd.php
Ana e Bruno

Warning: Undefined array key 2 in /home/ana/site/d-qtd.php on line 4
NULL

O que aconteceu: há mais variáveis do lado esquerdo do que itens no array. Acontece muito com explode, quando uma linha do arquivo veio incompleta ("Ana;29" em vez de "Ana;29;Recife").

Como resolver: confira a quantidade com count antes, ou complete o array com valores padrão. Para chaves de nome, o aviso cita a chave: Undefined array key "email".

Fatal error: Cannot mix keyed and unkeyed array entries in assignments
<?php
$aluna = ["nome" => "Ana", "idade" => 29];
["nome" => $nome, $idade] = $aluna;
$ php d-misturar.php

Fatal error: Cannot mix keyed and unkeyed array entries in assignments in /home/ana/site/d-misturar.php on line 3
Stack trace:
#0 {main}

O que aconteceu: na mesma desestruturação, uma variável tem chave ("nome" =>) e a outra não. O PHP não aceita misturar as duas formas.

Como resolver: escolha uma: ["nome" => $nome, "idade" => $idade] = $aluna;.

Warning: Cannot use string as array
<?php
[$a, $b] = null;
var_dump($a, $b);
[$c] = "texto";
var_dump($c);
$ php d-naoarray.php
NULL
NULL

Warning: Cannot use string as array in /home/ana/site/d-naoarray.php on line 4
NULL

O que aconteceu: o lado direito não era um array. Com null, o PHP fica em silêncio e todas as variáveis viram null (perigoso: o erro passa despercebido). Com uma string ou um número, ele avisa.

Como resolver: confira de onde vem o valor. Um caso comum é uma função que devolve false ou null quando falha, em vez do array esperado.

Only arrays and Traversables can be unpacked, string given
<?php
$letras = [...range("a", "c"), ..."xyz"];
$ php d-spread-str.php

Fatal error: Uncaught Error: Only arrays and Traversables can be unpacked, string given in /home/ana/site/d-spread-str.php:2
Stack trace:
#0 {main}
  thrown in /home/ana/site/d-spread-str.php on line 2

O que aconteceu: o spread só "despeja" arrays (e alguns objetos que se comportam como listas, os Traversables). Uma string não é um array de letras no PHP.

Como resolver: transforme em array antes: ...str_split("xyz") ou ...mb_str_split("xyz") para textos com acentos.


Referência rápida

Você quer…Código
Desmontar pela posição[$a, $b, $c] = $array;
A mesma coisa, forma antigalist($a, $b, $c) = $array;
Pular itens[$a, , $c] = $array;
Desmontar pelas chaves["nome" => $n, "nota" => $x] = $aluna;
Trocar duas variáveis[$a, $b] = [$b, $a];
Cortar um texto em variáveis[$d, $m, $a] = explode("/", $data);
No foreachforeach ($lista as [$x, $y]) / foreach ($alunos as ["nome" => $n])
Vários níveis[$a, [$b, $c]] = $array;
Juntar arrays (spread)[...$a, ...$b], ["x", ...$a]

Missão final

Missão: cada linha do arquivo de notas da Ana tem o formato nome;nota;cidade. Dentro do foreach, use explode e desestruturação ([$nome, $nota, $cidade] = …) para mostrar uma linha como Bruno (Olinda) tirou 7.0 para cada aluno. Repare na ordem dos campos.

<?php
$linhas = ["Ana;9.5;Recife", "Bruno;7.0;Olinda", "Carla;8.5;Caruaru"];

foreach ($linhas as $linha) {
    $partes = explode(";", $linha);
    echo $partes[0], "\n";
}
<?php
$linhas = ["Ana;9.5;Recife", "Bruno;7.0;Olinda", "Carla;8.5;Caruaru"];

foreach ($linhas as $linha) {
    [$nome, $nota, $cidade] = explode(";", $linha);
    echo "$nome ($cidade) tirou $nota\n";
}
$ php notas.php
Ana (Recife) tirou 9.5
Bruno (Olinda) tirou 7.0        « 7.0, com o zero: veio do texto, não virou número
Carla (Caruaru) tirou 8.5

Esse é o começo da leitura de arquivos CSV, que você vai ver por inteiro na aula CSV.


Exercícios

1. Hora e minuto

Complete para $hora receber "14" e $minuto receber "30":

= explode(":", "14:30");

2. Só a cidade

Complete para pegar só a chave "cidade" na variável $cidade:

[] = $aluna;

3. Trocar

Complete para trocar os valores de $x e $y:

[$x, $y] = ;

4. Depois de [, $b] = ["um", "dois", "três"];, quanto vale $b?

5. Qual é o resultado de [...["a", "b"], ...["c"]]?

6. O que acontece em [$a, $b, $c] = [1, 2];?


Resumo

  • [$a, $b] = $array; (ou list($a, $b)) põe os itens em variáveis, pela posição.
  • Itens sobrando são ignorados; variáveis sobrando ganham null e um aviso. Vírgulas vazias pulam itens.
  • ["chave" => $var] = $array; desmonta pelas chaves, em qualquer ordem. Não misture com a forma sem chaves.
  • [$a, $b] = [$b, $a]; troca dois valores.
  • No foreach: foreach ($alunos as ["nome" => $nome]).
  • O spread [...$a, ...$b] junta arrays, como o array_merge (chaves de nome: PHP 8.1+).