I just had some very strange behavior with a simple php script I was writing. I reduced it to the minimum necessary to recreate the bug:
<?php
$arr = array("foo",
"bar",
"baz");
foreach ($arr as &$item) { /* do nothing by reference */ }
print_r($arr);
foreach ($arr as $item) { /* do nothing by value */ }
print_r($arr); // $arr has changed....why?
?>
This outputs:
Array
(
[0] => foo
[1] => bar
[2] => baz
)
Array
(
[0] => foo
[1] => bar
[2] => bar
)
Is this a bug or some really strange behavior that is supposed to happen?
After the first foreach loop, $item is still a reference to some value which is also being used by $arr[2]. So each foreach call in the second loop, which does not call by reference, replaces that value, and thus $arr[2], with the new value.
So loop 1, the value and $arr[2] become $arr[0], which is 'foo'.
Loop 2, the value and $arr[2] become $arr[1], which is 'bar'.
Loop 3, the value and $arr[2] become $arr[2], which is 'bar' (because of loop 2).
The value 'baz' is actually lost at the first call of the second foreach loop.
This is the behavior of a referenced item, and not a bug. It would be similar to running something like:
for ($i = 0; $i < count($arr); $i++) { $item = $arr[$i]; }
A foreach loop isn't special in nature in which it can ignore referenced items. It's simply setting that variable to the new value each time like you would outside of a loop.