接上篇,这里一开始是sapi的初始化
1. sapi_startup函数
SAPI_API void sapi_startup(sapi_module_struct *sf)
{
sf->ini_entries = NULL;
sapi_module = *sf;
sapi_globals_ctor(&sapi_globals);
reentrancy_startup();
}
以上将win32平台和多线程安全的代码删除了,总共就4行。
最后一个reentrancy_startup是一个线程安全开启的情况下才有效的函数,其他情况下是一个宏
#if !defined(ZTS)
#undef PHP_NEED_REENTRANCY
#endif
#if defined(PHP_NEED_REENTRANCY)
void reentrancy_startup(void);
void reentrancy_shutdown(void);
#else
#define reentrancy_startup()
#define reentrancy_shutdown()
#endif
2. sapi_globals_ctor 初始化全部变量 sapi_globals
static void sapi_globals_ctor(sapi_globals_struct *sapi_globals)
{
memset(sapi_globals, 0, sizeof(*sapi_globals));
zend_hash_init_ex(&sapi_globals->known_post_content_types, 8, NULL, _type_dtor, 1, 0);
php_setup_sapi_content_types();
}
初始化默认接受的POST请求类型
#define DEFAULT_POST_CONTENT_TYPE "application/x-www-form-urlencoded"
#define MULTIPART_CONTENT_TYPE "multipart/form-data"
static const sapi_post_entry php_post_entries[] = {
{ DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler },
{ MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, NULL, rfc1867_post_handler },
{ NULL, 0, NULL, NULL }
};
int php_setup_sapi_content_types(void)
{
sapi_register_post_entries(php_post_entries);
return SUCCESS;
}
SAPI_API int sapi_register_post_entries(const sapi_post_entry *post_entries)
{
const sapi_post_entry *p=post_entries;
while (p->content_type) {
if (sapi_register_post_entry(p) == FAILURE) {
return FAILURE;
}
p++;
}
return SUCCESS;
}
SAPI_API int sapi_register_post_entry(const sapi_post_entry *post_entry)
{
int ret;
zend_string *key;
if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
key = zend_string_init(post_entry->content_type, post_entry->content_type_len, 1);
GC_MAKE_PERSISTENT_LOCAL(key);
ret = zend_hash_add_mem(&SG(known_post_content_types), key,
(void *) post_entry, sizeof(sapi_post_entry)) ? SUCCESS : FAILURE;
zend_string_release_ex(key, 1);
return ret;
}
以上代码其实就做了一件事,系统默认接受两种post提交请求。
3. ini配置的输入
if (sapi_module == &cli_sapi_module) {
if (ini_entries) {
ini_entries = realloc(ini_entries, ini_entries_len + sizeof(HARDCODED_INI));
memmove(ini_entries + sizeof(HARDCODED_INI) - 2, ini_entries, ini_entries_len + 1);
memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI) - 2);
} else {
ini_entries = malloc(sizeof(HARDCODED_INI));
memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
}
ini_entries_len += sizeof(HARDCODED_INI) - 2;
}
sapi_module->ini_entries = ini_entries;
这里是将硬编码的几个ini参数存入缓存,其硬编码参数如下
const char HARDCODED_INI[] =
"html_errors=0\n"
"register_argc_argv=1\n"
"implicit_flush=1\n"
"output_buffering=0\n"
"max_execution_time=0\n"
"max_input_time=-1\n\0";
4. 启动模块
cli启动时,使用的是cli_sapi_module对象,其内容如下
static sapi_module_struct cli_sapi_module = {
"cli", /* name */
"Command Line Interface", /* pretty name */
php_cli_startup, /* startup */
php_module_shutdown_wrapper, /* shutdown */
NULL, /* activate */
sapi_cli_deactivate, /* deactivate */
sapi_cli_ub_write, /* unbuffered write */
sapi_cli_flush, /* flush */
NULL, /* get uid */
NULL, /* getenv */
php_error, /* error handler */
sapi_cli_header_handler, /* header handler */
sapi_cli_send_headers, /* send headers handler */
sapi_cli_send_header, /* send header handler */
NULL, /* read POST data */
sapi_cli_read_cookies, /* read Cookies */
sapi_cli_register_variables, /* register server variables */
sapi_cli_log_message, /* Log message */
NULL, /* Get request time */
NULL, /* Child terminate */
STANDARD_SAPI_MODULE_PROPERTIES
};
其启动函数是php_cli_startup
static int php_cli_startup(sapi_module_struct *sapi_module) /* {{{ */
{
if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
return FAILURE;
}
return SUCCESS;
}
最终调用php_module_startup
接下来将分多篇说明php_module_startup