2

I've stepped upon one very interesting issue with foreach cycles in PHP. I have an array and two (quite similar) foreach cycles declared in one scope.

The interesting thing is that the second foreach doesn't work properly if it uses the same variable name as the first one and (at the same time) if the first one uses references (to the array items).

E.g.

$my_array = array("one", "two", "three", "four");
foreach($my_array as &$my_item) {

}

foreach($my_array as $my_item) {
  $second_array[] = $my_item;
}

Then the $second_array array doesn't contain "one", "two", "three", "four" but actually "one", "two", "three", "three".

Could someone explain to me why that is? Because I have honestly no idea, the two variables should have different scopes, it works just fine when no references are used...

//The fix is quite simple, apart from the obvious merging the two foreach cycles into just one , it also helps to change the 'item property' name of one of the foreach cycles (e.g. $my_item_1). The thing is, I don't want to fix it, I want to understand it :).

EDIT: This works fine.

$my_array = array("one", "two", "three", "four");
foreach($my_array as $my_item) {

}

foreach($my_array as $my_item) {
  $second_array[] = $my_item;
}

This works fine as well.

$my_array = array("one", "two", "three", "four");
foreach($my_array as &$my_item) {

}

foreach($my_array as $my_item_1) {
  $second_array[] = $my_item_1;
}
Petrroll
  • 741
  • 7
  • 29
  • could you fill in the body for the first loop so we can see what it is doing? are you modifying `$my_item` at all in that loop? – Jeff Lambert Jul 15 '14 at 15:07
  • It works as I wrote (e.g. not as one would expect) even with empty bodies (e.g. the examples work as described in the post (I've tested them)). – Petrroll Jul 15 '14 at 15:09

1 Answers1

4

It's explained in the foreach() manual page:

Warning

Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().

$my_array = array("one", "two", "three", "four");
foreach($my_array as &$my_item) {

}
unset($my_item);  //unset()

foreach($my_array as $my_item) {
  $second_array[] = $my_item;
}

Here is a really good answer: How 'foreach' actually works.

Community
  • 1
  • 1
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • 1
    Thanks! I thought that $value is declared only in the inner scope of the foreach it belongs to... PHP is surely an interesting language. – Petrroll Jul 15 '14 at 15:43