Problem Description
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 answers along the lines of "this is how you loop an array with `foreach`".
---
For a long time I assumed that `foreach` worked with the array itself. Then I found many references to the fact that it works with a *copy* of the array, and I have since assumed this to be the end of the story. But I recently got into a discussion on the matter, and after a little experimentation found that this was not in fact 100% true.
Let me show what I mean. For the following test cases, we will be working with the following array:
$array = array(1, 2, 3, 4, 5);
[Test case 1](http://codepad.org/7DIeObk9):
foreach ($array as $item) {
echo "$item\n";
$array[] = $item;
}
print_r($array);
/* Output in loop: 1 2 3 4 5
$array after loop: 1 2 3 4 5 1 2 3 4 5 */
This clearly shows that we are not working directly with the source array - otherwise the loop would continue forever, since we are constantly pushing items onto the array during the loop. But just to be sure this is the case:
[Test case 2](http://codepad.org/nirz6Ufh):
foreach ($array as $key => $item) {
$array[$key + 1] = $item + 2;
echo "$item\n";
}
print_r($array);
/* Output in loop: 1 2 3 4 5
$array after loop: 1 3 4 5 6 7 */
This backs up our initial conclusion, we are working with a copy of the source array during the loop, otherwise we would see the modified values during the loop. *But...*
If we look in the [manual](http://php.net/manual/en/control-structures.foreach.php), we find this statement:
>When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array.
Right... this seems to suggest that `foreach` relies on the array pointer of the source array. But we've just proved that we're *not working with the source array*, right? Well, not entirely.
[Test case 3](http://codepad.org/6n20ooMy):
// Move the array pointer on one to make sure it doesn't affect the loop
var_dump(each($array));
foreach ($array as $item) {
echo "$item\n";
}
var_dump(each($array));
/* Output
array(4) {
[1]=>
int(1)
["value"]=>
int(1)
[0]=>
int(0)
["key"]=>
int(0)
}
1
2
3
4
5
bool(false)
*/
So, despite the fact that we are not working directly with the source array, we are working directly with the source array pointer - the fact that the pointer is at the end of the array at the end of the loop shows this. Except this can't be true - if it was, then [test case 1](http://codepad.org/7DIeObk9) would loop fore...
AI-Generated Solution
Powered by LMSouq AI · GPT-4.1-mini
Analyzing problem and generating solution…
Was this solution helpful?