一、php_startup_auto_globals 初始化常用的全局变量
void php_startup_auto_globals(void)
{
zend_register_auto_global(zend_string_init_interned("_GET", sizeof("_GET")-1, 1), 0, php_auto_globals_create_get);
zend_register_auto_global(zend_string_init_interned("_POST", sizeof("_POST")-1, 1), 0, php_auto_globals_create_post);
zend_register_auto_global(zend_string_init_interned("_COOKIE", sizeof("_COOKIE")-1, 1), 0, php_auto_globals_create_cookie);
zend_register_auto_global(zend_string_init_interned("_SERVER", sizeof("_SERVER")-1, 1), PG(auto_globals_jit), php_auto_globals_create_server);
zend_register_auto_global(zend_string_init_interned("_ENV", sizeof("_ENV")-1, 1), PG(auto_globals_jit), php_auto_globals_create_env);
zend_register_auto_global(zend_string_init_interned("_REQUEST", sizeof("_REQUEST")-1, 1), PG(auto_globals_jit), php_auto_globals_create_request);
zend_register_auto_global(zend_string_init_interned("_FILES", sizeof("_FILES")-1, 1), 0, php_auto_globals_create_files);
}
二、zend_set_utility_values 保存支持的扩展
zuv.html_errors = 1;
zuv.import_use_extension = ".php";
zuv.import_use_extension_length = (uint32_t)strlen(zuv.import_use_extension);
void zend_set_utility_values(zend_utility_values *utility_values)
{
zend_uv = *utility_values;
zend_uv.import_use_extension_length = (uint32_t)strlen(zend_uv.import_use_extension);
}
三、php_startup_sapi_content_types 注册几个数据处理函数
1. 读取post数据的函数
SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(void))
{
if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
sapi_module.default_post_reader = default_post_reader;
return SUCCESS;
}
sapi_register_default_post_reader(php_default_post_reader);
2. 处理数据的函数
SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray))
{
if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
sapi_module.treat_data = treat_data;
return SUCCESS;
}
sapi_register_treat_data(php_default_treat_data);
3. 过滤函数
SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len), unsigned int (*input_filter_init)(void))
{
if (SG(sapi_started) && EG(current_execute_data)) {
return FAILURE;
}
sapi_module.input_filter = input_filter;
sapi_module.input_filter_init = input_filter_init;
return SUCCESS;
}
sapi_register_input_filter(php_default_input_filter, NULL);
这里的SG和EG分辨是sapi_globals和executor_globals全局结构
# define SG(v) (sapi_globals.v)
# define EG(v) (executor_globals.v)
四、php_register_internal_extensions_func 内部扩展注册
这是一个函数指针,其赋值位于main/main.c
PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_internal_extensions;
内部模块列表:
static zend_module_entry * const php_builtin_extensions[] = {
phpext_standard_ptr
#if HAVE_BCMATH
,phpext_bcmath_ptr
#endif
#if HAVE_CALENDAR
,phpext_calendar_ptr
#endif
,phpext_com_dotnet_ptr
#if HAVE_CTYPE
,phpext_ctype_ptr
#endif
#if HAVE_DATE
,phpext_date_ptr
#endif
#if HAVE_FTP
,phpext_ftp_ptr
#endif
#if HAVE_HASH
,phpext_hash_ptr
#endif
#if HAVE_ICONV
,phpext_iconv_ptr
#endif
#if HAVE_MBSTRING
,phpext_mbstring_ptr
#endif
#if HAVE_UODBC
,phpext_odbc_ptr
#endif
#if HAVE_PCRE || HAVE_BUNDLED_PCRE
,phpext_pcre_ptr
#endif
,phpext_reflection_ptr
#if HAVE_PHP_SESSION
,phpext_session_ptr
#endif
#if HAVE_TOKENIZER
,phpext_tokenizer_ptr
#endif
#if HAVE_ZLIB
,phpext_zlib_ptr
#endif
#if HAVE_LIBXML
,phpext_libxml_ptr
#if HAVE_DOM
,phpext_dom_ptr
#endif
#if HAVE_SIMPLEXML
,phpext_simplexml_ptr
#endif
#endif
#if HAVE_XML
,phpext_xml_ptr
#endif
#if HAVE_XML && HAVE_WDDX
,phpext_wddx_ptr
#endif
#if HAVE_SPL
,phpext_spl_ptr
#endif
#if HAVE_XML && HAVE_XMLREADER
,phpext_xmlreader_ptr
#endif
#if HAVE_XML && HAVE_XMLWRITER
,phpext_xmlwriter_ptr
#endif
};
除了第一个模块phpext_standard_ptr, 其他模块的启用都需要在执行configure的时候设置对应的参数,否则不会启用。这些模块都是静态编译,所以不需要写到ini文件里。关于模块的详细分析,这个之后再讲。
五、php_register_extensions_bc 注册额外的PHP模块
在cli模式下,这个是空的
如果是fpm模式下,会有一个额外的模块注册 cgi_module_entry
static const zend_function_entry cgi_fcgi_sapi_functions[] = {
PHP_FE(fastcgi_finish_request, cgi_fcgi_sapi_no_arginfo)
PHP_FE(fpm_get_status, cgi_fcgi_sapi_no_arginfo)
PHP_FE(apache_request_headers, cgi_fcgi_sapi_no_arginfo)
PHP_FALIAS(getallheaders, apache_request_headers, cgi_fcgi_sapi_no_arginfo)
PHP_FE_END
};
static zend_module_entry cgi_module_entry = {
STANDARD_MODULE_HEADER,
"cgi-fcgi",
cgi_fcgi_sapi_functions,
PHP_MINIT(cgi),
PHP_MSHUTDOWN(cgi),
NULL,
NULL,
PHP_MINFO(cgi),
NO_VERSION_YET,
STANDARD_MODULE_PROPERTIES
};
也即多了几个跟请求相关的函数
六、php_ini_register_extensions 注册写于ini的扩展(包括Zend和PHP)
七、zend_startup_modules 启动PHP扩展
主要就是调用每个扩展的PHP_MINIT
八、zend_startup_extensions 启动Zend扩展
主要就是调用每个扩展的startup
关于php扩展和zend扩展这里特别说明一下,在内部,php扩展叫模块(module),zend扩展叫扩展(extension)
九、zend_collect_module_handlers 收集各个模块有效的PHP_RINIT, PHP_RSHUTDOWN和post_RSHUTDOWN以及类的静态成员,以便清理是调用
十、将额外的函数注册到标准扩展中(此扩展包含了绝大数php内置函数)
if (sapi_module.additional_functions) {
if ((module = zend_hash_str_find_ptr(&module_registry, "standard", sizeof("standard")-1)) != NULL) {
EG(current_module) = module;
zend_register_functions(NULL, sapi_module.additional_functions, NULL, MODULE_PERSISTENT);
EG(current_module) = NULL;
}
}
在cli模式下有三个函数
static const zend_function_entry additional_functions[] = {
ZEND_FE(dl, arginfo_dl)
PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
PHP_FE(cli_get_process_title, arginfo_cli_get_process_title)
PHP_FE_END
};
在fpm模式下,这个为空
cgi_sapi_module.additional_functions = NULL;
十一、禁用通过ini配置的函数和类
php_disable_functions();
php_disable_classes();
禁用函数的ini选项是 disable_functions
禁用类的ini选项是 disable_classes