php 中while执行完,【PHP7源码学习】2019-04-04 PHP中while的实现

grape

引入

在我们平常写PHP代码总是会用到while语句,那么我们有没有去考虑过while语句是怎么实现的呢?

我们来看下面的这段代码:

$a = 1;

while($a){

}

我们知道这段代码是个死循环,毋庸置疑,但是在PHP中,它是如何做到的呢?请看下文。

分析

首先,我们自己分析一下这个while语句,如果让我们来设计,我们会如何设计呢?笔者写出脑补几点:

PHP是C语言编写的,直接去沿用C的语法,while套用。

在源码设计中加入goto语句。

for循环嵌套if语句

等等(大家可以头脑风暴下)

接下来我们看一下PHP源码中是如何实现的。

俗话说,实践是检验真理的唯一道路,那么我们就去gdb一下,调试上边的代码,用事实说话。

接下来是gdb的过程,因为是ast树的构建过程,之前文章已经详细解释过,此处不再赘述,文章传送门:2019-05-07 发布【PHP源码学习】2019-03-21 AST,gdb过程如图1所示:

bVbuXoA?w=1621&h=469

此时我们可以知道AST就是长的图二的样子,如图2:

bVbuZgy?w=609&h=515

ast树建立好了,但是他执行了什么指令,我们还是得去看看他的opcode是什么,继续gdb代码,执行到zend_file_context_end之后,此时opcode已经执行完成,我们打印下gdb结果,如图3所示:

bVbuXsm?w=1645&h=309

ps:在图三中我们可以看到有四条指令,对应下分别为:

ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER:对应$a = 1;

ZEND_JMP_SPEC_HANDLER:跳转到下一条opcode

ZEND_JMPNZ_SPEC_CV_HANDLER:进行while循环,如果循环条件不为0则跳回循环体

ZEND_RETURN_SPEC_CONST_HANDLER:PHP虚拟机自动给脚本加的return

由此我们可以发现while语句的实现由ZEND_JMP_SPEC_HANDLER与ZEND_JMPNZ_SPEC_CV_HANDLER来实现,学过汇编的同学应该知道,JMP是无条件跳转的意思,在这里是跳转到下一个opcode,即JMPNZ,JMPNZ则是条件不为0时才会跳转。由此我们可以画出while的执行流程,如图所示:

bVbuYsH?w=450&h=621

至此我们可以得到while的执行流程了,当然如果想知道这些是如何进行运作的,建议大家去看一看pass_two这个函数,里边有如何设置opcode的。

结论

while语句并不是嵌套C语言的while语句,也不是我们之前的种种猜测,他的核心是通过jump,jumpnz来进行控制的。

ps:设计者可真是个天才。 :手动滑稽

延伸

如果说明白了while语句,那么do_while又是怎么一回事呢?大家可以自行思考一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值