PHP基础架构(1.4 PHP生命周期)
四、生命周期
PHP整个生命周期划分为以下几个阶段:模块初始化阶段(module starup)、请求初始化阶段(request starup)、执行脚本阶段(execute script)、请求关闭阶段(request shutdown)、模块关闭阶段(module shutdown)。
1.模块初始化阶段
该阶段主要进行PHP框架、Zend引擎的初始化操作。该阶段的入口函数为php_module_startup()。这个阶段一般只在SAPI启动时执行一次,对于Fpm而言,就是在Fpm的master进程启动时执行的。
该阶段的几个主要处理:
- **SAPI:sapi_activate(),初始化请求信息SG(request_info)、设置读取POST请求的handle等,在modle startup阶段处理完成后调用sapi_deactivate()。
- 启动PHP输出:php_output_startup()。
- 初始化垃圾回收器:gc_globals_ctor(),分配zend_gc_globals内存。
- 启动zend引擎:zend_startup(),主要操作:
启动内存池start_memory_manager();
设置一些util函数句柄(如zned_error_cb、zend_printf、zend_write等);
设置Zend虚拟机编译、执行器的函数句柄zend_compile_file\zend_execute_ex,以及垃圾回收的函数句柄gc_collect_cycles;
分配函数符号表(CG(function_table))、类符号表(CG(class_table))、常量符号表(EG(zend_constants))等,如果是多线程的话,还会分配编译器、执行器的全局变量;
注册Zend核心扩展:zend_startup_builtin_functions(),这个扩展是内核提供的,该过程将注册Zend核心扩展提供的函数,比如strlen(返回字符串的长度)、define(定义一个常量)、func_get_args(获取函数参数列表的数组)、class_exists(检查类是否已定义)等;
注册Zend定义的标准常量:zend_register_standard_constants(),比如:E_ERROR、E_WARNING、E_ALL、TRUE、FALSE等;
注册$GLOBALS超全局变量的获取handler;
分配php.ini配置的存储符号表:EG(ini_directives)。
- 注册PHP定义的常量:PHP_VERSION、PHP_ZTS、PHP_SAPI等等。
- 解析php.ini:解析完成后所有的php.ini配置保存在configuration_hash哈希表中。
- 映射PHP、Zend核心的php.ini配置:根据解析出的php.ini,获取对应的配置值,将最终的配置插入EG(ini_directives)哈希表。
- 注册用于获取$_GET、$_POST、$_COOKIE、$_SERVER、$_ENV、$_REQUEST、$_FILES变量的handler。
- 注册静态编译扩展:php_register_internal_extensions_func()。
- 注册动态加载的扩展:php_ini_register_extensions(),将php.ini中配置的扩展加载到PHP中。
- 回调个扩展定义的module startup钩子函数,即通过PHP_MINIT_FUNCTION()定义的函数。
- 注册php.ini中禁用的函数、类:disable_functions、disable_classes。
2.请求初始化阶段
该阶段是在请求处理签每个请求都会经历的一个阶段,对于Fpm而言,是在worker进程accept一个请求且读取、解析完请求数据后的一个阶段。该阶段的处理函数为php_request_startup()。
主要的处理有:
- **输出:php_output_activate()。
- **Zend引擎:zend_activate(),主要操作如下所述:
重置垃圾回收器:gc_reset();
初始化编译器:init_compiler();
初始化执行器:init_executor,将EG(function_table)、EG(class_table)分别指向CG(function_table)、CG(class_table),所以在PHP的编译、执行期间,EG(function_table)与CG(function_table)、EG(class_table)与CG(class_table)是同一个值;另外还会初始化全局变量符号表EG(symbol_table)、include过得文件符号表EG(included_files);
初始化此法扫描器:startup_scanner()。
- **SAPI:sapi_activate()。
- 回调个扩展定义的request startup钩子函数:zend_active_modules()。
3.执行脚本阶段
该阶段包括PHP代码的编译、执行两个核心阶段,这是Zend引擎最重要的功能。在编译阶段,PHP脚本将经历从PHP源代码到抽象语法树再到opline指令的转化过程,最终生成的opline指令就是Zend引擎可识别的执行指令,这些指令接着背执行器执行,这就是PHP代码解释执行的过程。这个借口的入口函数为php_execute_script()。
4.请求关闭阶段
在php脚本解释执行完成后将进入请求关闭阶段,这个阶段将flush输出内容、发送HTTP应答header头、清理全局变量、关闭编译器、关闭执行器等。另外,在该阶段将毁掉各个扩展的request shutdown钩子函数。该阶段是请求初始化阶段的相反操作,与请求初始化的处理一一对应。
5.模块关闭阶段
该阶段在SAPI关闭时执行,与模块初始化阶段对应,这个阶段主要进行资源的清理、PHP各模块的关闭操作,同时,将会钓个扩展的module shutdown钩子函数。具体的处理函数为php_module_shutdown()。
注:此博文为本人学习《PHP7内核剖析》(秦朋 / 著)一书所记下的笔记以方便日后查看,如有侵权请私信本人删文。