Strano comportmento di foreach

<?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.