Guia Completo da Função array_walk_recursive() do PHP
Aprenda array_walk_recursive() do PHP: aplique um callback a cada folha em arrays aninhados, modifique valores por referência, com exemplos e armadilhas.
array_walk_recursive() aplica um callback a todo valor não-array (folha) em um array, descendo em arrays aninhados automaticamente. Ao contrário de um foreach manual, você não precisa escrever a recursão, e ao contrário de array_map(), ele pode modificar o array original no lugar recebendo cada valor por referência.
Este capítulo aborda a assinatura da função, como ela percorre arrays aninhados, como modificar valores por referência, o papel do terceiro argumento opcional e as armadilhas que pegam as pessoas de surpresa (objetos, chaves e o que conta como uma "folha").
Sintaxe
array_walk_recursive(array|object &$array, callable $callback, mixed $arg = null): true$array— o array a percorrer. É passado por referência, então o callback pode alterar seu conteúdo.$callback— um callable invocado uma vez por folha, recebendo($value, $key). Declare$valuecomo&$valuepara editar o array no lugar.$arg— um argumento extra opcional passado (por valor) ao callback como seu terceiro parâmetro.
A função retorna true. Apenas valores folha chegam ao callback — chaves que contêm sub-arrays são percorridas, mas nunca passadas a ele.
Como ela percorre arrays aninhados
O callback é acionado para cada elemento escalar e, sempre que um elemento é em si um array, array_walk_recursive() entra nesse array também. O próximo exemplo imprime cada par chave: valor, incluindo os que estão dentro do array aninhado:
Saída:
0: a
1: b
0: c
1: d
2: e
3: fObserve que o próprio array aninhado (o que contém c, d, e) não é passado ao callback — apenas suas folhas são. As chaves que você recebe são as chaves dentro de cada nível, por isso c, d, e reportam 0, 1, 2 novamente.
Modificando valores por referência
O uso mais comum desta função é transformar toda uma estrutura aninhada no lugar. Receba o valor &$value por referência e atribua a ele. Aqui, cada preço recebe 10% de imposto adicionado, independentemente de quão profundamente esteja aninhado:
<?php
$prices = [
'fruit' => ['apple' => 1.00, 'pear' => 2.00],
'drinks' => ['water' => 0.50],
];
array_walk_recursive($prices, function (&$value, $key) {
$value = round($value * 1.10, 2); // add 10% tax
});
print_r($prices);
?>Saída:
Array
(
[fruit] => Array
(
[apple] => 1.1
[pear] => 2.2
)
[drinks] => Array
(
[water] => 0.55
)
)Passando dados extras com o terceiro argumento
O $arg opcional é entregue ao callback (por valor) como um terceiro parâmetro — útil para passar configurações sem uma closure. Aqui, uma string de prefixo é fornecida uma vez e reutilizada para cada folha:
<?php
$data = ['name' => 'ada', 'team' => ['bob', 'cara']];
array_walk_recursive($data, function ($value, $key, $prefix) {
echo $prefix . ucfirst($value) . "\n";
}, ">> ");
?>Saída:
>> Ada
>> Bob
>> CaraComo $arg é passado por valor, você não pode usá-lo para acumular resultados entre chamadas. Para construir um valor, capture uma variável por referência com use (&$total) em vez disso:
<?php
$data = [1, [2, 3], 4];
$sum = 0;
array_walk_recursive($data, function ($value, $key) use (&$sum) {
$sum += $value;
});
echo "Sum: $sum\n"; // Sum: 10
?>Armadilhas
- Apenas arrays são percorridos recursivamente. Uma folha é qualquer coisa que não seja um array — incluindo objetos. Um
stdClassdentro dos seus dados é passado ao callback como um único valor, não percorrido internamente. - Os nós de array aninhados nunca chegam ao callback. Se precisar agir sobre arrays contêineres em si (não apenas as folhas), use
array_walk()ou umforeachrecursivo manual. - Modificar requer
&$value. Sem a referência, atribuições dentro do callback são descartadas e o array original permanece inalterado. - As chaves podem se repetir entre níveis. O
$keyque você recebe é a chave no seu próprio nível, então o mesmo valor de chave pode aparecer em ramificações diferentes.
Funções relacionadas
array_walk()— mesma ideia, mas apenas um nível de profundidade.array_map()— retorna um novo array em vez de mutar no lugar.array_filter()— mantém elementos que passam em um teste.- PHP Arrays — conceitos básicos de arrays e outros auxiliares.