为什么foreach在我们没有在循环中修改它时复制数组?

时间:2013-08-11 14:51:50

标签: php arrays foreach php-internals

在一篇博文"PHP Internals: When does foreach copy"中,NikiC在这样的代码中声明:

Snippet 1

$array = range(0, 100000);
foreach ($array as $key => $value) {
    xdebug_debug_zval('array'); // array is not copied, only refcount is increased
}

foreach不会复制数组,因为foreach修改$array的唯一内容是它的内部数组指针。

他还说过这样的代码:

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将复制数组,因为如果没有,第1行中的$array变量将会被更改。

然而, foreach修改$array的唯一内容是它的内部数组指针。那么,为什么第1行中$array变量的内部数组指针发生了变化呢?在片段1中没关系,为什么它在片段2中很重要?

为什么foreach需要在代码段2中复制数组,即使我们没有在循环中修改它?

2 个答案:

答案 0 :(得分:2)

这是因为在第二种情况下, $ array 通过值传递给函数test()。因此,在函数内部创建了 $ array 的副本,foreach()在副本上工作。如果通过引用函数test()传递 $ array ,情况会有所不同。

有关按值传递与按引用传递的信息,see this question

答案 1 :(得分:1)

您的问题已在您关联的文章中得到解答。它在

部分给出
  

未引用,引用计数> 1

解释说需要复制结构,因为数组指针移动了,这不会影响外部数组。