上篇文章我们分析了生命周期的模块初始化阶段, 大部分是初始化全局变量和各种宏的定义, 今天我们来学习一下五大生命周期的第二阶段 -- 请求初始化阶段 (php_request_startup).
一, 概览
我们先对请求初始化阶段内的函数做个概览.
函数 | 说明 |
---|---|
php_output_activate() | 重置输出全局变量,初始化输出相关堆栈 |
zend_activate() | 初始化 Zend 引擎 |
sapi_activate() | 初始化 SG 宏,调各 sapi 钩子函数 activate |
zend_signal_activate() | 信号处理 |
zend_set_timeout() | 设置超时时间 |
php_hash_environment() | 初始化 PHP 请求的全局变量 |
zend_activate_modules() | 调用各扩展定义的 request_startup 钩子函数 |
二, 源码分析
2.1,php_output_activate
重新为 output_globals 分配内存, 初始化与输出处理程序相关的堆栈, 并将 OG 宏的 flags 设置为激活状态.
- //main/output.c
- PHPAPI int php_output_activate(void)
- {
- #ifdef ZTS
- memset((*((void ***) ZEND_TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(output_globals_id)], 0, sizeof(zend_output_globals));
- #else
- memset(&output_globals, 0, sizeof(zend_output_globals));
- #endif
- zend_stack_init(&OG(handlers), sizeof(php_output_handler *));
- OG(flags) |= PHP_OUTPUT_ACTIVATED;
- return SUCCESS;
- }
- 2.2,zend_activate
zend 引擎的初始化, 主要作用为重置垃圾回收, 初始化编译器, 初始化执行器, 初始化扫描器.
函数 | 说明 |
---|---|
gc_reset() | 重置垃圾回收 |
init_compiler() | 初始化编译器 |
init_executor() | 初始化执行器 |
startup_scanner() | 初始化扫描器 |
2.3,sapi_activate
对 SG 宏内的一些变量进行初始化, 并调用当前 sapi_module_struct 中定义的钩子函数 activate() 以及 input_filter_init(), 但是在 cli 模式下, 这两个钩子函数都没有实现, 返回了 null.
- //main/SAPI.c
- SAPI_API void sapi_activate(void)
- {
- zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), (void (*)(void *)) sapi_free_header, 0);
- SG(sapi_headers).send_default_content_type = 1;
- /*
- SG(sapi_headers).http_response_code = 200;
- */
- SG(sapi_headers).http_status_line = NULL;
- SG(sapi_headers).mimetype = NULL;
- SG(headers_sent) = 0;
- ZVAL_UNDEF(&SG(callback_func));
- SG(read_post_bytes) = 0;
- SG(request_info).request_body = NULL;
- ......
- }
- 2.4,php_hash_environment
为 http_globals 分配内存, 初始化 auto_globals, 解析请求参数并存放到全局变量中.
- PHPAPI int php_hash_environment(void)
- {
- memset(PG(http_globals), 0, sizeof(PG(http_globals)));
- zend_activate_auto_globals();
- if (PG(register_argc_argv)) {
- php_build_argv(SG(request_info).query_string, &PG(http_globals)[TRACK_VARS_SERVER]);
- }
- return SUCCESS;
- }
- 2.5,zend_activate_modules
该函数通过遍历注册在 module_registry 的所有模块, 调用每个模块的钩子函数 request_startup() 进行初始化.
- ZEND_API void zend_activate_modules(void) /* {{{ */
- {
- zend_module_entry **p = module_request_startup_handlers;
- while (*p) {
- zend_module_entry *module = *p;
- if (module->request_startup_func(module->type, module->module_number)==FAILURE) {
- zend_error(E_WARNING, "request_startup() for %s module failed", module->name);
- exit(1);
- }
- p++;
- }
- }
来源: https://www.cnblogs.com/enochzzg/p/9581544.html