<?php $a = arrays('a', 'b', 'c', 'd'); foreach ($a as &$v) { } foreach ($a as $v) { } print_r($a); ?>
Penso che sia un programma normale, ma questo è l'output che sto ottenendo:
Array ( [0] => a [1] => b [2] => c [3] => c )
Qualcuno può spiegarmelo per favore?
Questo è un comportmento PHP ben documentato Vedere l' avviso nella pagina di foreach di php.net
avvertimento
Il riferimento di un valore $ e l'ultimo elemento dell'arrays rimangono anche dopo il ciclo foreach . Si consiglia di distruggerlo con unset ().
$a = arrays('a', 'b', 'c', 'd'); foreach ($a as &$v) { } unset($v); foreach ($a as $v) { } print_r($a);
MODIFICARE
Tentativo di una guida passo-passo a ciò che sta realmente accadendo qui
$a = arrays('a', 'b', 'c', 'd'); foreach ($a as &$v) { } // 1st iteration $v is a reference to $a[0] ('a') foreach ($a as &$v) { } // 2nd iteration $v is a reference to $a[1] ('b') foreach ($a as &$v) { } // 3rd iteration $v is a reference to $a[2] ('c') foreach ($a as &$v) { } // 4th iteration $v is a reference to $a[3] ('d') // At the end of the foreach loop, // $v is still a reference to $a[3] ('d') foreach ($a as $v) { } // 1st iteration $v (still a reference to $a[3]) // is set to a value of $a[0] ('a'). // Because it is a reference to $a[3], // it sets $a[3] to 'a'. foreach ($a as $v) { } // 2nd iteration $v (still a reference to $a[3]) // is set to a value of $a[1] ('b'). // Because it is a reference to $a[3], // it sets $a[3] to 'b'. foreach ($a as $v) { } // 3rd iteration $v (still a reference to $a[3]) // is set to a value of $a[2] ('c'). // Because it is a reference to $a[3], // it sets $a[3] to 'c'. foreach ($a as $v) { } // 4th iteration $v (still a reference to $a[3]) // is set to a value of $a[3] ('c' since // the last iteration). // Because it is a reference to $a[3], // it sets $a[3] to 'c'.
Il primo ciclo foreach non apport alcuna modifica alla matrix, proprio come ci aspetteremmo. Tuttavia, fa sì che $v
venga assegnato un riferimento a ciascuno degli elementi $a
, in modo che, al momento del primo ciclo, $v
sia, in realtà, un riferimento a $a[2]
.
Non appena viene avviato il secondo ciclo, $v
viene ora assegnato il valore di ciascun elemento. Tuttavia, $v
è già un riferimento a $a[2];
pertanto, qualsiasi valore assegnato ad esso verrà automaticamente copiato nell'ultimo elemento dell'arrays!
Quindi, durante la prima iterazione, $a[2]
diventerà zero, quindi uno, e poi uno nuovamente, essendo effettivamente copiati su se stesso. Per risolvere questo problema, dovresti sempre disinserire le variables che usi nei loops foreach di riferimento per-o, meglio ancora, evitare di utilizzare il primo insieme.