Let me prefix this by saying that I know what foreach
is, does and how to use it. This question concerns how it works under the bonnet, and I don\'t want any an
In example 3 you don't modify the array. In all other examples you modify either the contents or the internal array pointer. This is important when it comes to PHP arrays because of the semantics of the assignment operator.
The assignment operator for the arrays in PHP works more like a lazy clone. Assigning one variable to another that contains an array will clone the array, unlike most languages. However, the actual cloning will not be done unless it is needed. This means that the clone will take place only when either of the variables is modified (copy-on-write).
Here is an example:
$a = array(1,2,3);
$b = $a; // This is lazy cloning of $a. For the time
// being $a and $b point to the same internal
// data structure.
$a[] = 3; // Here $a changes, which triggers the actual
// cloning. From now on, $a and $b are two
// different data structures. The same would
// happen if there were a change in $b.
Coming back to your test cases, you can easily imagine that foreach
creates some kind of iterator with a reference to the array. This reference works exactly like the variable $b
in my example. However, the iterator along with the reference live only during the loop and then, they are both discarded. Now you can see that, in all cases but 3, the array is modified during the loop, while this extra reference is alive. This triggers a clone, and that explains what's going on here!
Here is an excellent article for another side effect of this copy-on-write behaviour: The PHP Ternary Operator: Fast or not?