PHP,编译foreach和opline
我试图弄清楚PHP是如何解释foreach语句的。这导致我在执行伪foreach脚本时使用了PHP,编译foreach和opline,php,arrays,compiler-construction,php-internals,Php,Arrays,Compiler Construction,Php Internals,我试图弄清楚PHP是如何解释foreach语句的。这导致我在执行伪foreach脚本时使用了gdb 我最终在zend_compile.c中,在zend_compile_foreach()函数中。我看到了对宏ZEND_FE_FETCH_R的调用,该宏移动我们循环的数组/对象的内部指针 有几件事我不明白: 值实际如何返回到zend\u compile\u foreach上下文 我们是否嵌套调用zend\u compile\u stmt(因此zend\u compile\u foreach)以实现迭
gdb
我最终在zend_compile.c中,在zend_compile_foreach()函数中。我看到了对宏ZEND_FE_FETCH_R的调用,该宏移动我们循环的数组/对象的内部指针
有几件事我不明白:
- 值实际如何返回到
zend\u compile\u foreach
上下文
- 我们是否嵌套调用
zend\u compile\u stmt
(因此zend\u compile\u foreach
)以实现迭代?那么代码是否编译了N次?N是数组/对象中的元素数
- 什么是opline??我到处都能看到,但我不知道这件事
也许有趣?我已经找到了这个问题/答案,但它是关于foreach用户行为的,不是关于内部实现和执行的,而是关于编译器代码的。它不会循环。生成的虚拟机指令循环。尝试phpdbg-p*test.php
查看生成的指令。opline是将由VM执行的实际指令。以前几乎所有的工作都是对这些指令进行词法分析和编译。2.zend_compile_foreach()write opline向前移动内部寻道器,将var的当前值写入该opline,执行循环代码块,然后跳回opnum_fetch,直到fetch通过fe_fetch_r_exit发出退出。所以没有循环,只有跳转(有点像goto?)到前一个操作码以使用新值再次执行代码。我说得对吗?