上篇文章讲述了模块初始化阶段之前的准备工作,本篇我来详细介绍PHP生命周期的五个阶段。
一、模块初始化阶段
我们先来看一下该阶段的每个函数的作用。

1.1、sapi_initialize_request_empty函数
// main/SAPI.c SAPI_API void sapi_initialize_empty_request(void) { SG(server_context) = NULL; SG(request_info).request_method = NULL; SG(request_info).auth_digest = SG(request_info).auth_user = SG(request_info).auth_password = NULL; SG(request_info).content_type_dup = NULL; }这个函数主要为前面定义的SG宏中的成员变量进行初始化。
1.2、sapi_activate函数
// 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_status_line = NULL; SG(sapi_headers).mimetype = NULL; SG(headers_sent) = 0; ...... /* Handle request method */ if (SG(server_context)) { ...... if (sapi_module.activate) { sapi_module.activate(); } } if (sapi_module.input_filter_init) { sapi_module.input_filter_init(); } }函数的前半部分主要还是对SG宏的成员变量进行初始化。后半部分先是调用了sapi_module_struct内部实现的activate函数,又调用了input_filter_init函数,但是在CLI模式并没有实现这两个函数,只是返回了NULL。代码如下:
NULL, /* activate */1.3、php_output_startup函数
//main/output.c PHPAPI void php_output_startup(void) { ZEND_INIT_MODULE_GLOBALS(output, php_output_init_globals, NULL); zend_hash_init(&php_output_handler_aliases, 8, NULL, NULL, 1); zend_hash_init(&php_output_handler_conflicts, 8, NULL, NULL, 1); zend_hash_init(&php_output_handler_reverse_conflicts, 8, NULL, reverse_conflict_dtor, 1); php_output_direct = php_output_stdout; }我们先来看ZEND_INIT_MODULE_GLOBALS宏做了什么事情:
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor) \ globals_ctor(&module_name##_globals);由代码得知,该宏只是做了一层替换,替换后的内容为:
php_output_init_globals(&output_globals);那php_output_init_globals函数又做了什么呢?
//main/output.c static inline void php_output_init_globals(zend_output_globals *G) { ZEND_TSRMLS_CACHE_UPDATE(); memset(G, 0, sizeof(*G)); }该函数通过memset函数对
