【发布时间】:2013-08-12 22:46:45
【问题描述】:
在一篇博文"PHP Internals: When does foreach copy" 中,NikiC 表示在这样的代码中:
片段 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 的唯一修改是它的内部数组指针。
他还在这样的代码中表示:
片段 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 变量的内部数组指针被更改,为什么会有影响呢?在 sn-p 1 中无关紧要,为什么在 sn-p 2 中很重要?
为什么foreach需要复制sn-p 2中的数组,即使我们没有在循环中修改它?
【问题讨论】:
-
据我所知,这可能并不多,您的数组始终作为 COPY 传递,因为您没有将其作为参考传递。
-
@Jorge,关键是为什么php在sn-p 1中只软复制(增加引用计数),而在sn-p 2中硬复制?为什么我们不能在 sn-p 2 中进行软拷贝,因为没有对数组进行修改?
-
@PeeHaa,解释了第一个 sn-p,但不是第二个。
-
我读过那篇博客,我认为原因很清楚,因为
$array变量未在发生foreach的函数范围内定义,这里的一个困惑是,@ 987654335@不会copy$array,倒不如说会被test() function复制过来,这不完全对。因为当foreach迭代数组时,它必须能够访问它的内部指针才能获得key和value,因此,它必须在副本或原始指针上工作。 -
@Akam,$array 不是由 test() 函数硬复制的,只是引用计数增加,也就是软复制。
标签: php arrays foreach php-internals