Page 1 of 1
strange behaviour in foreach
Posted: Fri May 30, 2008 6:25 am
by periklis
Could someone please explain me the following strange behaviour:
Code: Select all
<?php
echo "<pre>";
$arr = array(array(3 => 'foo'), false);
print_r($arr);
foreach ($arr as &$value) {}
print_r($arr);
foreach ($arr as $value) {}
print_r($arr);
echo "</pre>";
?>
Displays:
Code: Select all
Array
(
[0] => Array
(
[3] => foo
)
[1] =>
)
Array
(
[0] => Array
(
[3] => foo
)
[1] =>
)
Array
(
[0] => Array
(
[3] => foo
)
[1] => Array
(
[3] => foo
)
)
Thanks in advance!
Re: strange behaviour in foreach
Posted: Fri May 30, 2008 9:22 am
by dml
After running this:
Any assignment you make to $value will also assign to the last element in $arr, that is $arr[1].
Does that explain it sufficiently?
Re: strange behaviour in foreach
Posted: Fri May 30, 2008 11:48 am
by periklis
Well, it does explain it, but not sufficiently

I haven't made any assignments to the $arr after running the foreach code. I haven't done anything at all. Why does a simple loop over the array elements assign to the last value its previous one? Is this the normal behaviour?
Re: strange behaviour in foreach
Posted: Fri May 30, 2008 12:47 pm
by dml
I'm trying to avoid long verbal explanations because I'll only make it sound more complicated than it is. Better to edge towards an understanding by playing with code examples. For a start, do you entirely understand what's going on below, and when you execute it, do you get the result you expected? It's nearly the same thing as your code example, but the foreach's have been temporarily removed:
Code: Select all
$arr = array(1, 2, 3);
$value =& $arr[2];
$value = 100;
print_r($arr);
Re: strange behaviour in foreach
Posted: Fri May 30, 2008 1:09 pm
by periklis
Yeap, I understand this.
Re: strange behaviour in foreach
Posted: Fri May 30, 2008 1:26 pm
by dml
Each iteration of a foreach loop involves the assignment of the loop variable followed by the execution of the loop body, which is empty in your example, so your foreach loops are actually just sequences of assignments. So below is your example with the loops decomposed into sequences of assignments. There's no extra tricks in this example than in the previous example, there are just a few more assignments to keep track of.
Code: Select all
$arr = array(array(3 => 'foo'), false);
print_r($arr);
// BREAK DOWN: foreach ($arr as &$value) {}
$value =& $arr[0];
$value =& $arr[1];
print_r($arr);
// BREAK DOWN foreach ($arr as $value) {}
$value = $arr[0];
$value = $arr[1];
print_r($arr);
Re: strange behaviour in foreach
Posted: Sat May 31, 2008 3:27 am
by periklis
Now I think I'm starting to get it. So, when the first loop finishes, $value points to the same place as $arr[1].
When the second loop starts, $value becomes $arr[0], but since $value is a reference to $arr[1], $arr[1] also becomes $arr[0].
Thus in the end, you get the last value being the same as the first previous one
Thank your really very much, this explanation really helped me!