没有虚拟主机怎么建网站,国家企业信用信息官网,h5免费制作平台火蚁邀请函怎么写,玩具公司网站建设方案PHP程序的执行流程为了以后能开发PHP扩展#xff0c;就一定要了解PHP的执行顺序。这篇文章就是为C开发PHP扩展做铺垫。Web环境我们假设为Apache。在编译PHP的时候,为了能够让Apache支持PHP#xff0c;我们会生成一个mod_php5.so的模块。Apache加载这个模块#xff0c;在url访…PHP程序的执行流程为了以后能开发PHP扩展就一定要了解PHP的执行顺序。这篇文章就是为C开发PHP扩展做铺垫。Web环境我们假设为Apache。在编译PHP的时候,为了能够让Apache支持PHP我们会生成一个mod_php5.so的模块。Apache加载这个模块在url访问.php文件的时候就会转给mod_php5.so模块来处理。这个就是我们常说的SAPI。英文名字是Server Application Programming Interface。SAPI其实是一个统称其下有 ISAPICLI SAPICGI等。有了它就可以很容易的跟其他东西交互比如APACHE,IIS,CGI等。Apache启动后会将 mod_pho5.so 模块的hook handler注册进来当Apache检测到访问的url是一个php文件时这时候就会把控制权交给SAPI。进入到SAPI后首先会执行 sapi/apache/mod_php5.c 文件的 php_init_handler 函数这里摘录一段代码static void php_init_handler(server_rec *s, pool *p){register_cleanup(p, NULL, (void (*)(void *))apache_php_module_shutdown_wrapper, (void (*)(void *))php_module_shutdown_for_exec);if (!apache_php_initialized) {apache_php_initialized 1;#ifdef ZTStsrm_startup(1, 1, 0, NULL);#endifsapi_startup(apache_sapi_module);php_apache_startup(apache_sapi_module);}#if MODULE_MAGIC_NUMBER 19980527{TSRMLS_FETCH();if (PG(expose_php)) {ap_add_version_component(PHP/ PHP_VERSION);}}#endif}该函数主要调用两个函数sapi_startup(apache_sapi_module);php_apache_startup(apache_sapi_module);SAPI_API void sapi_startup(sapi_module_struct *sf){sf-ini_entries NULL;sapi_module *sf;.................sapi_globals_ctor(sapi_globals);................virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */..................reentrancy_startup();}sapi_startup 创建一个 sapi_globals_struct 结构体。*sapi_globals_struct 保存了Apache请求的基本信息如服务器信息Header编码等。sapi_startup 执行完毕后再执行 php_apache_startup 。static int php_apache_startup(sapi_module_struct *sapi_module){if (php_module_startup(sapi_module, apache_module_entry, 1) FAILURE) {return FAILURE;} else {return SUCCESS;}}php_module_startup 内容太多这里介绍一下大致的作用初始化 zend_utility_functions 结构.这个结构是设置zend的函数指针,比如错误处理函数,输出函数,流操作函数等.设置环境变量.加载php.ini配置.加载php内置扩展.写日志.注册php内部函数集.调用 php_ini_register_extensions, 加载所有外部扩展开启所有扩展一些清理操作.重点说一下 3,4,7,8 加载php.ini配置if (php_init_config(TSRMLS_C) FAILURE) {return FAILURE;}php_init_config 函数会在这里检查所有php.ini配置并且找到所有加载的模块添加到 php_extension_lists 结构中。加载php内置扩展调用 zend_register_standard_ini_entries 加载所有php的内置扩展如array,mysql等。调用 php_ini_register_extensions ,加载所有外部扩展。main/php_ini.cvoid php_ini_register_extensions(TSRMLS_D){zend_llist_apply(extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC);zend_llist_apply(extension_lists.functions, php_load_php_extension_cb TSRMLS_CC);zend_llist_destroy(extension_lists.engine);zend_llist_destroy(extension_lists.functions);}zend_llist_apply 函数遍历 extension_lists 执行会调用函数 php_load_php_extension_cbstatic void php_load_zend_extension_cb(void *arg TSRMLS_DC){zend_load_extension(*((char **) arg));}该函数最后调用if ((module_entry zend_register_module_ex(module_entry TSRMLS_CC)) NULL) {DL_UNLOAD(handle);return FAILURE;}将扩展信息放到 Hash 表 module_registry 中Zend/zend_API.cif (zend_hash_add(module_registry, lcname, name_len1, (void *)module, sizeof(zend_module_entry), (void**)module_ptr)FAILURE) {zend_error(E_CORE_WARNING, Module \%s\ already loaded, module-name);efree(lcname);return NULL;}最后 zend_startup_modules(TSRMLS_C) 对模块进行排序并检测是否注册到 module_registry HASH表里。zend_startup_extensions(); 执行 extension-startup(extension); 启动扩展。