Mějme pole s několika úrovněmi:
$array = [
'a' => [
'aa' => 10,
'ab' => 250,
'ac' => 100,
],
'b' => [
'ba' => 20,
'bb' => [
'bba' => 20,
'bbb' => 20,
'bbc' => 20,
],
'bc' => 10,
],
];
Máme za úkol vypsat všechny klíče a jejich hodnoty. Samozřejmě bychom mohli použít neprimitivnější postup a použít foreach nad polem. V něm bychom testovali, jestli je aktuálně procházený prvek také pole. Pokud ano, pak bychom jej procházeli a vypisovali jeho klíče a hodnoty. Pokud ne, jen vypíšeme jeho klíč a hodnotu.
To se ale dá použít jen tehdy, když přesně víme kolik úrovní zanoření máme. Navíc to není moc pěkný kód a bude zmatek v proměnných:
foreach ($array as $key => $val) {
if(is_array($val)) {
foreach ($val as $key2 => $val2) {
if(is_array($val2)) {
foreach ($val2 as $key3 => $val3) {
echo $key3 . ":" . $val3 . "<br>";
}
} else {
echo $key2 . ":" . $val2 . "<br>";
}
}
} else {
echo $key . ":" . $val . "<br>";
}
}
Trochu lepší je použití rekurzivně volané funkce. Tam je nám jedno kolik úrovní vnoření existuje. Funkce může vypadat třeba takto:
function printAllVals($key, $val) {
if (!is_array($val)) {
echo $key . ":" . $val . "<br>";
return;
}
foreach($val as $key2 => $val2) {
$this->printAllVals($key2, $val2);
}
}
printAllVals([], $array);
Při prvním volání funkce předávám jako parametr prázdné pole. Jak říkám – je to už univerzálněji použitelné, ale jaksi to pořád ještě není ono. To pravé je použít vestavěné funkce pro práci s kolekcemi přímo v PHP:
$iterArray = new \RecursiveIteratorIterator( new \RecursiveArrayIterator($array));
foreach ($iterArray as $key => $val) {
echo $key . ":" . $val . "<br>";
}
Je to čisté a krásné, funguje to bezvadně a nic nám v kódu nepřekáží.