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.
- A forma curta
[$a, $b] = $array;e a antigalist($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ço | A 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 arrays | Desde |
|---|---|
| Arrays com chaves numéricas (listas) | PHP 7.4+ |
| Arrays com chaves de nome | PHP 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 antiga | list($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 foreach | foreach ($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":
2. Só a cidade
Complete para pegar só a chave "cidade" na variável $cidade:
3. Trocar
Complete para trocar os valores de $x e $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;(oulist($a, $b)) põe os itens em variáveis, pela posição.- Itens sobrando são ignorados; variáveis sobrando ganham
nulle 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 oarray_merge(chaves de nome: PHP 8.1+).