【问题标题】:Why does foreach copy the array when we did not modify it in the loop? [duplicate]当我们没有在循环中修改它时,为什么foreach会复制数组? [复制]
【发布时间】: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 迭代数组时,它必须能够访问它的内部指针才能获得keyvalue,因此,它必须在副本或原始指针上工作。
  • @Akam,$array 不是由 test() 函数硬复制的,只是引用计数增加,也就是软复制。

标签: php arrays foreach php-internals


【解决方案1】:

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

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

【讨论】:

【解决方案2】:

您的问题已在您链接到的文章中得到解答。在章节中给出了

未引用,refcount > 1

说明需要结构的副本,因为数组指针会移动,这一定不会影响外部数组。

【讨论】:

  • 你能举例说明它是如何失败的吗?为什么外部数组的内部指针发生变化很重要?在第一个 sn-p 中,数组指针也会移动,并且它不需要在那里进行硬拷贝。
  • 如果你把一个变量赋给一个函数,你期望函数返回后变量不变。更改数组指针也是对变量的更改,这绝对不能发生!
  • 你说改变内部数组指针也是改变变量。那为什么第一个sn-p不做硬拷贝呢?第一个 sn-p 也修改了数组。 $arrayforeach 之前和foreach 之后的状态在第一个sn-p 中也是不同的。
猜你喜欢
  • 2018-03-27
  • 2019-03-07
  • 1970-01-01
  • 2019-10-17
  • 2022-01-04
  • 2016-07-31
  • 2015-11-27
  • 2019-01-09
  • 2017-02-15
相关资源
最近更新 更多