PHP 在底层(C 语言层面)的代码执行流程可以大致分为以下几个步骤:
解析器初始化:当 PHP 服务启动时,会调用解析器(Zend Engine)的初始化函数进行初始化,包括各种全局变量的初始化,内存池的初始化。
文件读取和解析:解析器会读取并解析 PHP 文件,将其转换为语法树,并将其中的函数和变量信息保存在符号表中。
编译器生成 opcodes:编译器将语法树转换为 opcode(操作码)序列,这是一种类似于字节码的中间表示形式,可以被解释器执行。
执行 opcodes:解释器会按照 opcode 序列的顺序逐个执行 opcode,其中涉及到内存管理、变量解析、函数调用等过程。
Zend API 处理:Zend API 提供了一些操作符,用于在 C 代码中与 PHP 代码进行交互,比如获取变量值、调用 PHP 函数。
实现扩展:PHP 扩展是一组 C 函数,可以通过链接到 PHP 二进制文件来扩展 PHP 的功能,涉及到底层数据传递、内存管理等技术。
输出:当 PHP 程序需要输出数据(HTML 文档、JSON 数据等)时,PHP 会调用输出(Output)机制,将数据发送给客户端。
清理:当 PHP 程序执行完毕或发生错误时,需要清理内存、回收资源等环境清理工作。
SAPI运行PHP都经过下面几个阶段:
1、模块初始化阶段(Module init) :
即调用每个拓展源码中的的PHP_MINIT_FUNCTION中的方法初始化模块,进行一些模块所需变量的申请,内存分配等。
2、请求初始化阶段(Request init) :
即接受到客户端的请求后调用每个拓展的PHP_RINIT_FUNCTION中的方法,初始化PHP脚本的执行环境。
3、执行PHP脚本
4、请求结束(Request Shutdown) :
这时候调用每个拓展的PHP_RSHUTDOWN_FUNCTION方法清理请求现场,并且ZE开始回收变量和内存。
5、关闭模块(Module shutdown) :
Web服务器退出或者命令行脚本执行完毕退出会调用拓展源码中的PHP_MSHUTDOWN_FUNCTION 方法
php-fpm的执行流程
1、nginx/apache接收请求
2、nginx/apache将请求传递给php-fpm
3、php-fpm初始化环境,如创建变量列表
4、php-fpm调用各个扩展/模块的RINIT
5、php-fpm磁盘读取php文件(使用opcache可避免)
6、php-fpm词法分析、语法分析、编译成opcode(使用opcache可避免)
7、php-fpm执行opcode 包括8.9.10.11
8、框架初始化,如实例化各种类,包括如容器、控制器、路由、中间件等。
9、框架连接数据库并权限验证,连接redis
10、框架执行业务逻辑
11、框架关闭数据库、redis连接
12、php-fpm释放资源、销毁所有类定义、实例、销毁符号表等
13、php-fpm顺序调用各个扩展/模块的RSHUTDOWN方法
14、php-fpm将结果转发给nginx/apache
15、nginx/apache将结果返回给客户端