php的cli模式下的内部实现流程概述

知识准备:

1 PHP源码主要结构:

README.XXX 帮助文件

Build 编译相关文件

Ext php的各种函数的实现

Main 实现php的核心架构代码,不包含底层中间代码的解析

Zend 中间代码opcode的相关逻辑及底层执行实现

Pear php相关扩展库

Sapi 各种服务器抽象层的代码

TSRM 线程相关库

Tests 测试用例

Win32 windows平台相关的代码

2 启动php的模式(主要接口代码在sapi中)

服务器模式

Apache php_mod, fastcgi

Php_mod:作为apache的一个扩展模块进行php脚本的解析

fastcgi:通过fastcgi协议进行php脚本的解析

Nginx : fastcgi

 剩下的服务器模式感觉不是那么主流,先不管了

phpcli模式

命令行运行模式,从命令行中执行php脚本就切到这里了

嵌入式模式

这个实际应该比较稀有,先放着吧

3 各个模式的启动流程

Mint -> rint -> script->  rshutdown  -> mshutdown

模块初始化 -> 请求初始化 ->处理具体的业务 -> 关闭请求 -> 关闭模块

在非cli模式下,mint 将在服务器启动阶段进行,当请求到达时,不在启动mint,直接进行rint阶段,处理完请求执行rshutdown

同样,每个请求也并不执行mshutdown,这个行为在服务器关闭或重启时统一一次调用。

cli模式可能是个例外,他还是需要每次都载入模块的,即执行mint

 

开始正文:

cli模式为例(这样就不用牵扯到服务器了),我们先走一圈

启动代码在 sapi/cli/php_cli.c

代码从main函数开始启动

主体运行流程:

填充sapi模块的结构

这里定义的sapi_module_structcli_sapi_module。

启动sapi,进行sapi的一些全局设置

sapi_startup(&cli_sapi_module)

运行sapi模块的startup,对各种模块,扩展,资源进行注册和初始化

cli_sapi_module.startup(&cli_sapi_module)

这里面各种startupregister,例如几个重要的

php_module_startup()

zend_startup(&zuf, NULL TSRMLS_CC);zend_startup_modules(TSRMLS_C);

zend_startup_extensions();

初始化请求

执行php_request_startup();

编译php文件,把编译后的opcode执行

php_execute_script(&file_handle TSRMLS_CC);

这里面的编译命令为

EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);实际调用的是zend_language_scanner.c里面的

ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)

这里最终的执行命令为

zend_execute(EG(active_op_array) TSRMLS_CC);实际调用的是

Zend_vm_excute.h里面的

ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)

请求关闭释放的相关工作

执行php_request_shutdown();

关闭释放相关的各种模块

php_module_shutdown(TSRMLS_C);

关闭sapi相关资源

sapi_shutdown();

Ps:

常听人说php源代码比较乱,感觉跟nginx代码比起来。。的确有些让人郁闷很多。。

原文地址:https://www.cnblogs.com/wully/p/2323013.html