首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

PHP内核探索之ZEND虚拟机2-方法调用

接着上文的从一个变量开始。我们在编写程序的时候,首先会定义相关变量,然后开始定义方法,用来实现业务。但是当我们在PHP中调用一个方法时,Zend虚拟机是如何处理的呢?

function demo()

{

echo "Hello MRTAL!";

}

demo();

我们通过 vld 查看生成的 OPCODE。出现了两个 OPCODE 指令执行栈,是因为我们自定义了一个 PHP 函数。在第一个执行栈上,调用自定义函数会执行两个 OPCODE 指令:INIT_FCALL 和 DO_FCALL。

compiled vars: none

line #* E I O op fetch ext return operands

-------------------------------------------------------------------------------------

2 0 E > NOP

6 1 INIT_FCALL 'foo'

2 DO_FCALL 0

3 > RETURN 1

compiled vars: none

line #* E I O op fetch ext return operands

-------------------------------------------------------------------------------------

3 0 E > ECHO 'test'

4 1 > RETURN null

其中,INIT_FCALL 准备了执行函数时所需要的上下文数据。DO_FCALL 负责执行函数。DO_FCALL 的处理函数根据不同的调用情况处理了大量逻辑,我摘取了其中执行用户定义的函数的逻辑部分:

可以看到,DO_FCALL 首先将调用函数前的上下文数据保存到 call->prev_execute_data,然后调用 i_init_func_execute_data 函数,将自定义函数对象中的 op_array(每个自定义函数会在编译的时候生成对应的数据,其数据结构中包含了函数的 OPCODE 数组) 赋值给新的执行上下文对象。

然后,调用 zend_execute_ex 函数,开始执行自定义的函数。zend_execute_ex 实际上就是前面提到的 execute_ex 函数(默认是这样,但扩展可能重写 zend_execute_ex 指针,这个 API 让 PHP 扩展开发者可以通过覆写函数达到扩展功能的目的,不是本篇的主题,不准备深入探讨),只是上下文数据被替换成当前函数所在的上下文数据。

我们可以这样理解,最外层的代码就是一个默认存在的函数(类似 C 语言中的 main()函数),和用户自定义的函数本质上是没有区别的。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180424G1R0BC00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券