php的数组都有一个内部指针,指向数组的元素,初始化的时候是第一个,我要便利数组,让内部指针逐个移动
$arr = array ('a', 'b', 'c', 'd', 'e'); foreach ($arr as $k => $v) { $curr = current($arr); echo "{$k} => {$v} -- {$curr}\n"; }
得到结果是
0 => a -- b 1 => b -- b 2 => c -- b 3 => d -- b 4 => e -- b
内部指针向后移动了一位就再也没动过了。。。
foreach对这个数组做了什么呢?为什么呢?
我要让指针遍历数组,得到如下结果改怎么做呢?
0 => a -- a 1 => b -- b 2 => c -- c 3 => d -- d 4 => e -- e
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
这个问题我在bugs.php.net上回答过: https://bugs.php.net/bug.php?id=63752
1. at the beginning of foreach: ZEND_FE_RESET which increase the refoucnt of $a
2. then FE_FETCH, reset internal pointer of $a
3. then current, current declared to accept a reference, but $a is not a ref and refcount > 1 , then -> separation
PHP 的数组指针操作函数:
pos()
http://cn2.php.net/manual/en/function...end()
http://cn2.php.net/manual/en/function...prev()
http://cn2.php.net/manual/en/function...next()
http://cn2.php.net/manual/en/function...each()
http://cn2.php.net/manual/en/function...reset()
http://cn2.php.net/manual/en/function...current()
http://cn2.php.net/manual/en/function...foreach()
操作原始数组的一个拷贝,如果需要移动指针,使用while
结构加上each()
来实现。参见 http://cn2.php.net/manual/en/function... 的 example #2。
php的所有变量实际上是用一个struct zval来表示的。
而数组就是其中的"HashTable *ht",实际上就是一个哈希表(Hash Table),表中的所有元素同时又组成一个双向链表,它的定义为:
这里有一个 Bucket *pInternalPointer ,就是被reset/current/next等函数用来遍历数组保存位置状态的。Bucket的实现如下,可以看到这就是个赤裸裸的链表节点。
而foreach的实现,则位于 ./Zend/zend_compile.h ,在解释期被flex翻译成由 zend_do_foreach_begin zend_do_foreach_cont zend_do_foreach_end 这三个函数(以及相关代码)组合起来。由于看起来比较晦涩,我就不贴出来了(实际上我也没看太懂),详情可以参考雪候鸟的这篇:深入理解PHP原理之foreach
最后附一段php代码的opcode