PHP扩展开发——用户代码的执行

PHP内核的实现与世界上绝大多数的程序一样,接收输入数据, 做相应处理然后输出(返回)结果。 我们编写的代码就是PHP接收的输入数据,PHP内核对我们编写的代码进行解释和运算, 最后返回相应的运算结果。

1、一切的开始: SAPI接口
SAPI(Server Application Programming Interface)指的是PHP具体应用的编程接口, 就像PC一样,无论安装哪些操作系统,只要满足了PC的接口规范都可以在PC上正常运行, PHP脚本要执行有很多种方式,通过Web服务器,或者直接在命令行下,也可以嵌入在其他程序中。

最常见的四种启动PHP方式如下:

  • CLI/CGI模式调用;
  • 多进程模块;
  • 多线程模块;
  • 嵌入式,C程序中调用Zend Engine;

PHP开始执行以后会经过两个主要的阶段:处理请求之前的开始阶段和请求之后的结束阶段。 开始阶段有两个过程:第一个过程是模块初始化阶段(MINIT), 在整个SAPI生命周期内(例如Apache启动以后的整个生命周期内或者命令行程序整个执行过程中), 该过程只进行一次。第二个过程是模块激活阶段(RINIT),该过程发生在请求阶段, 例如通过url请求某个页面,则在每次请求之前都会进行模块激活(RINIT请求开始)。

单进程的SAPI模式流程图如下:


PHP扩展开发——用户代码的执行_第1张图片

(1)Module init
扩展载入时调用,注册常量或者类初始化

PHP_MINIT_FUNCTION(myext)
{
    return SUCCESS;
}

(2)Request init
请求到达后,PHP会初始化执行脚本的基本环境。

PHP_RINIT_FUNCTION(myext)
{
    return SUCCESS;
}

(3)Request shutdown
请求处理完之后,一般脚本执行到末尾或者通过调用exit()或者die()函数,PHP进入结束阶段。

PHP_RSHUTDOWN_FUNCTION(myext)
{
    return SUCCESS;
}

(4)Module shutdown
SAPI生命周期结束

PHP_MSHUTDOWN_FUNCTION(myext)
{
    return SUCCESS;
}

这两种init和两种shutdown各会执行多少次,取决于上面提到的四种PHP启动方式,比如下面两种:

  • 多进程SAPI生命周期:


    PHP扩展开发——用户代码的执行_第2张图片
  • 多线程SAPI生命周期


    PHP扩展开发——用户代码的执行_第3张图片

2、PHP脚本的执行
PHP在读取到脚本文件后,Zend引擎对脚本文件进行词法分析,语法分析。然后编译成opcode执行。

PHP扩展开发——用户代码的执行_第4张图片

Opcode缓存就是把虚拟机编译的PHP中间码(Opcode)缓存起来,下一次再次运行同样页面时,直接解释这些代码即可,这样就省去了词法分析、语法编译、语法检查、虚拟机编译一些列过程,一定程度上提高了PHP运行速度,减轻了服务器压力。

参考资料:

  1. 《PHP核心技术与最佳实践》
  2. 《TIPI:深入理解PHP内核》

你可能感兴趣的:(PHP扩展开发——用户代码的执行)