There is a perfectly logical explanation and this is not a bug!
PHP 5 introduces the possibility of modifying the contents of the array directly by assigning the value of each element to the iterated variable by reference rather than by value. Consider this code, for example:
$a = array (’zero’,’one’,’two’);
foreach ($a as &$v) {
}
foreach ($a as $v) {
}
print_r ($a);
It would be natural to think that, since this little script does nothing to the array, it will not affect its contents... but that’s not the case! In fact, the script provides the following output:
Array
(
[0] => zero
[1] => one
[2] => one
)
As you can see, the array has been changed, and the last key now contains the value ’one’. How is that possible? The first foreach
loop does not make any change to the array, just as we would expect. However, it does cause $v
to be assigned a reference to each of $a
’s elements, so that, by the time the loop is over, $v
is, in fact, a reference to $a[2]
.
As soon as the second loop starts, $v
is now assigned the value of each element. However, $v
is already a reference to $a[2]
; therefore, any value assigned to it will be copied automatically into the last element of the arrays! Thus, during the first iteration, $a[2]
will become zero, then one, and then one again, being effectively copied on to itself. To solve this problem, you should always unset the variables you use in your by-reference foreach
loops—or, better yet, avoid using the former altogether.