Dopo il primo ciclo foreach, $item
è ancora presente un riferimento a un valore utilizzato anche da $arr[2]
. Quindi ogni foreach call nel secondo loop, che non chiama per riferimento, sostituisce quel valore, e quindi $arr[2]
, con il nuovo valore.
Quindi loop 1, il valore e $arr[2]
diventa $arr[0]
, che è 'pippo'.
Loop 2, il valore e $arr[2]
diventa $arr[1]
, che è 'bar'.
Loop 3, il valore e $arr[2]
diventa $arr[2]
, che è 'bar' (a causa del loop 2).
Il valore 'baz' viene effettivamente perso alla prima chiamata del secondo ciclo foreach.
Debug dell'output
Per ogni iterazione del ciclo, riecheggeremo il valore $item
e stamperemo ricorsivamente l'array $arr
.
Quando viene eseguito il primo ciclo, vediamo questo output:
foo
Array ( [0] => foo [1] => bar [2] => baz )
bar
Array ( [0] => foo [1] => bar [2] => baz )
baz
Array ( [0] => foo [1] => bar [2] => baz )
Alla fine del ciclo, $item
indica ancora lo stesso posto di $arr[2]
.
Quando viene eseguito il secondo ciclo, vediamo questo output:
foo
Array ( [0] => foo [1] => bar [2] => foo )
bar
Array ( [0] => foo [1] => bar [2] => bar )
bar
Array ( [0] => foo [1] => bar [2] => bar )
Noterai come ogni volta che un array inserisce un nuovo valore $item
, anch'esso aggiornato $arr[3]
con lo stesso valore, poiché entrambi puntano ancora nella stessa posizione. Quando il ciclo arriva al terzo valore dell'array, conterrà il valore bar
perché era stato appena impostato dalla precedente iterazione di quel ciclo.
E 'un errore?
No. Questo è il comportamento di un elemento referenziato e non un bug. Sarebbe simile a eseguire qualcosa di simile:
for ($i = 0; $i < count($arr); $i++) { $item = $arr[$i]; }
Un ciclo foreach non è di natura speciale in cui può ignorare gli elementi di riferimento. Sta semplicemente impostando quella variabile sul nuovo valore ogni volta che faresti fuori da un ciclo.