为什么PHP的foreach仅将其数组的指针前进一次(仅)? [英] Why does PHP's foreach advance the pointer of its array (only) once?
问题描述
这是一个好奇问题,关于在PHP中实现foreach
的背后原因.
This is a question of curiosity about the reasons behind the way foreach
is implemented within PHP.
考虑:
$arr = array(1,2,3);
foreach ($arr as $x) echo current($arr) . PHP_EOL;
它将输出:
2
2
2
我了解到foreach
将数组指针倒退到开始处;但是,为什么只增加一次呢?魔术盒子里发生了什么?这只是一件(丑陋的)人工制品吗?
I understand that foreach
rewinds array pointers to the beginning; however, why does it then increment it only once? What is happening inside the magic box?? Is this just an (ugly) artefact?
感谢@NickC-对于对zval
和refcount
感兴趣的其他人,您可以阅读基础知识
Thanks @NickC -- for anyone else curious about zval
and refcount
, you can read up on the basics here
推荐答案
在第一次迭代之前,$array
被软复制"以供在foreach
中使用.这意味着没有完成任何实际的复制,但是只有$array
的zval的refcount
增加到了2
.
Right before the first iteration the $array
is "soft copied" for use in foreach
. This means that no actual copy is done, but only the refcount
of the zval of $array
is increased to 2
.
在第一次迭代中:
- 该值已提取到
$x
. - 内部数组指针移动到下一个元素,即现在指向
2
. -
current
通过引用传递的$array
进行调用.由于引用的原因,PHP无法再与循环共享zval
,因此需要将其分隔(硬拷贝").
- The value is fetched into
$x
. - The internal array pointer is moved to the next element, i.e. now points to
2
. current
is called with$array
passed by reference. Due to the reference PHP cannot share thezval
with the loop anymore and it needs to be separated ("hard copied").
在随后的迭代中,$array
zval不再与foreach
zval关联.因此,其数组指针不再被修改,并且current
始终返回相同的元素.
On the following iterations the $array
zval thus isn't anymore related the the foreach
zval anymore. Thus its array pointer isn't modified anymore and current
always returns the same element.
顺便说一句,我在说明复制行为.在上下文中可能会引起关注,但它与该问题没有直接关系,因为它主要讨论的是硬拷贝.
By the way, I have written a small summary on foreach copying behavior. It might be of interest in the context, but it does not directly relate to the issue as it talks mostly about hard copying.
这篇关于为什么PHP的foreach仅将其数组的指针前进一次(仅)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!