In a blog post "PHP Internals: When does foreach copy", NikiC stated that in a code like this:
Snippet 1
$array = range(0, 100000);
foreach ($array as $key => $value) {
xdebug_debug_zval('array'); // array is not copied, only refcount is increased
}
foreach
will not copy the array because the only thing that foreach
modifies about $array
is it's internal array pointer.
He also stated that in a code like this:
Snippet 2
$array = range(0, 100000); // line 1
test($array);
function test($array) {
foreach ($array as $key => $value) { // line 4
xdebug_debug_zval('array'); // array is copied, refcount not increased
// ...
}
}
foreach
will copy the array because if it didn't, the $array
variable in line 1 would be changed.
However, the only thing that foreach
modifies about $array
is it's internal array pointer. So why does it matter if the internal array pointer of the $array
variable in line 1 is changed? It didn't matter in snippet 1, why did it matter in snippet 2?
Why does foreach
need to copy the array in snippet 2, even though we did not modify it in the loop?
$array
variable is not defined in the scope of the function where theforeach
takes place, one confusion here is that,foreach
will notcopy
the$array
, it's better to say that it will be copied by thetest() function
and this is not exactly right. Because whileforeach
iterates the array, it must has access to it's internal pointer to get thekey
andvalue
, therefore, it must work on a copy or the original one. – Annulation