Guida completa alla funzione array_walk_recursive() di PHP
Scopri array_walk_recursive() in PHP: applica un callback a ogni foglia in array annidati, modifica i valori per riferimento, con esempi e avvertenze.
array_walk_recursive() applica un callback a ogni valore non-array (foglia) in un array, discendendo automaticamente negli array annidati. A differenza di un foreach manuale, non è necessario scrivere la ricorsione da soli, e a differenza di array_map(), può modificare l'array originale sul posto prendendo ogni valore per riferimento.
Questo capitolo tratta la firma della funzione, come percorre gli array annidati, la modifica dei valori per riferimento, il ruolo del terzo argomento opzionale e le insidie che possono sorprendere (oggetti, chiavi e cosa si intende per "foglia").
Sintassi
array_walk_recursive(array|object &$array, callable $callback, mixed $arg = null): true$array— l'array da percorrere. Viene passato per riferimento, quindi il callback può modificarne il contenuto.$callback— un callable invocato una volta per ogni foglia, che riceve($value, $key). Dichiarare$valuecome&$valueper modificare l'array sul posto.$arg— un argomento extra opzionale passato (per valore) al callback come terzo parametro.
La funzione restituisce true. Solo i valori foglia raggiungono il callback — le chiavi che contengono sotto-array vengono percorse ma mai passate ad esso.
Come percorre gli array annidati
Il callback viene eseguito per ogni elemento scalare, e quando un elemento è a sua volta un array, array_walk_recursive() entra anche in quell'array. Il prossimo esempio stampa ogni coppia key: value, incluse quelle all'interno dell'array annidato:
Output:
0: a
1: b
0: c
1: d
2: e
3: fSi noti che l'array annidato stesso (quello che contiene c, d, e) non viene passato al callback — solo le sue foglie lo sono. Le chiavi ricevute sono le chiavi all'interno di ogni livello, ecco perché c, d, e riportano nuovamente 0, 1, 2.
Modifica dei valori per riferimento
L'uso più comune di questa funzione è trasformare un'intera struttura annidata sul posto. Si prende il valore &$value per riferimento e si assegna ad esso. Qui ogni prezzo riceve una tassa del 10% aggiunta, indipendentemente da quanto sia annidato:
<?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);
?>Output:
Array
(
[fruit] => Array
(
[apple] => 1.1
[pear] => 2.2
)
[drinks] => Array
(
[water] => 0.55
)
)Passare dati extra con il terzo argomento
L'$arg opzionale viene passato al callback (per valore) come terzo parametro — utile per passare configurazioni senza usare una closure. Qui una stringa prefisso viene fornita una volta e riutilizzata per ogni foglia:
<?php
$data = ['name' => 'ada', 'team' => ['bob', 'cara']];
array_walk_recursive($data, function ($value, $key, $prefix) {
echo $prefix . ucfirst($value) . "\n";
}, ">> ");
?>Output:
>> Ada
>> Bob
>> CaraPoiché $arg viene passato per valore, non è possibile usarlo per accumulare risultati tra le chiamate. Per costruire un valore, catturare invece una variabile per riferimento con use (&$total):
<?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
?>Insidie
- Solo gli array vengono ricorsivamente percorsi. Una foglia è qualsiasi cosa che non sia un array — inclusi gli oggetti. Un
stdClassall'interno dei dati viene passato al callback come singolo valore, non percorso al suo interno. - I nodi array annidati non raggiungono mai il callback. Se è necessario agire sugli array contenitore stessi (non solo sulle foglie), usare
array_walk()o unforeachricorsivo manuale. - La modifica richiede
&$value. Senza il riferimento, le assegnazioni all'interno del callback vengono scartate e l'array originale rimane invariato. - Le chiavi possono ripetersi tra i livelli. La
$keyricevuta è la chiave al proprio livello, quindi lo stesso valore di chiave può comparire in rami diversi.
Funzioni correlate
array_walk()— stessa idea, ma solo a un livello di profondità.array_map()— restituisce un nuovo array invece di modificare sul posto.array_filter()— mantiene gli elementi che superano un test.- PHP Arrays — concetti di base sugli array e altri helper.