PHP与WEB服务器交互的案例分析

  介绍

这篇文章主要介绍了PHP与WEB服务器交互的案例分析,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。

大家都知道,PHP需要在具体的WEB服务器中才能运行,例如Nginx, Apache等,但是PHP是怎样启动,又是怎样在服务器中运行,然后两者又是怎样进行交互的呢?

以Apache服务器为例,我们看看该服务器是怎样启动PHP,并调用PHP中的方法.Apache服务器启动并运行PHP时,一般是通过mod_php7模块的形式集成(如果是php5。*版本,就是mod_php5模块,模块后缀名根据PHP版本而定),mod_php7的结构如下(源码路径为PHP/sapi/apache2handler/mod_php7。c):

AP_MODULE_DECLARE_DATA模块php7_module={/*宏STANDARD20_MODULE_STUFF,包括版本,版本,模块索引,模块名,下个模块指针等信息*/create_php_config,/*创建每目录单独配置结构*/merge_php_config,/* */合并每目录单独配置结构   空,/*创建每个服务器配置结构*/空,/* */合并每台服务器配置结构   php_dir_cmds,/*模块定义的所有指令*/php_ap2_register_hook钩子*//*注册   };

当Apache需要调用PHP中的方法时,只需要将该请求通过mod_php7模块传达给PHP, PHP层处理完后将数据返回给Apache,整个过程就结束了(补充一下:Apache服务器启动PHP时,其实有两种加载方式,一种为静态加载,一种为动态加载,刚才讨论的mod_php5模块加载方式可以理解为静态加载,也就是需要重新启动Apache服务器,才能将PHP加载进去;动态加载不需要重启服务器,只需要通过发送信号的方式将PHP固定的模块加载到服务器,以达到PHP启动的目的,但是在进行动态加载前,需要将加载模块编译成动态链接库,然后将其配置到服务器的配置文件中)。上面已经给出Apache在PHP中模型的结构,下面给出Apache服务器中对应的模块结构,如下(该源代码在Apache中,下同):

struct module_struct {   int版本;   int minor_version;   int module_index;   const char *名称;   void * dynamic_load_handle;   struct module_struct *下;   无符号长魔法;   空白(* rewrite_args) (process_rec *过程);   void * (* create_dir_config) (apr_pool_t * p, char * dir);   void * (* merge_dir_config) (apr_pool_t * p, void * base_conf, void * new_conf);   void * (* create_server_config) (apr_pool_t * p, server_rec * s);   void * (* merge_server_config) (apr_pool_t * p, void * base_conf, void * new_conf);   const command_rec * cmds;   空白(* register_hooks) (apr_pool_t * p);   }

可以看得出php7_module和module_struct还是有很大不同,不过如果看到php7_module。STANDARD20_MODULE_STUFF这个宏的定义方式,你可能就会觉得这两个结构体很像,其实这个宏定义了module_struct中的前8个参数,定义如下:

# define STANDARD20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \   MODULE_MAGIC_NUMBER_MINOR, \   1,\   __FILE__, \   空,\   空,\   MODULE_MAGIC_COOKIE, \   空/*重写args点*/

然后php7_module.php_dir_cmds定义了模块的所有指令集合,具体定义内容如下(代码路径为php/sapi/apache2handler/apache_config。c):

const command_rec php_dir_cmds []={   AP_INIT_TAKE2 (“php_value" php_apache_value_handler, NULL, OR_OPTIONS,“PHP Modifier"价值),   AP_INIT_TAKE2 (“php_flag" php_apache_flag_handler, NULL, OR_OPTIONS,“PHP标记Modifier"),   AP_INIT_TAKE2 (“php_admin_value" php_apache_admin_value_handler, NULL, ACCESS_CONF | RSRC_CONF,“PHP价值修饰符(管理)   “),   AP_INIT_TAKE2 (“php_admin_flag" php_apache_admin_flag_handler, NULL, ACCESS_CONF | RSRC_CONF,“PHP标记修改器(管理)“),   AP_INIT_TAKE1 (“PHPINIDir" php_apache_phpini_set, NULL, RSRC_CONF,“包含php目录。ini file"),   {零}   };

也就是说,PHP层只给Apache提供了上述5个指令,每个指令的实现源码也在apache_config.c文件中,最后就剩php7_module.php_ap2_register_hook了,它定义的内容如下(代码路径为PHP/sapi/apache2handler/mod_php7。c):

空白php_ap2_register_hook (apr_pool_t * p)   {   ap_hook_pre_config (php_pre_config空,空,APR_HOOK_MIDDLE);   ap_hook_post_config (php_apache_server_startup空,空,APR_HOOK_MIDDLE);   ap_hook_handler (php_handler空,空,APR_HOOK_MIDDLE);   # ifdef ZEND_SIGNALS   ap_hook_child_init (zend_signal_init空,空,APR_HOOK_MIDDLE);   # endif   ap_hook_child_init (php_apache_child_init空,空,APR_HOOK_MIDDLE);   }

php7_module。php_ap2_register_hook函数包含4个钩子和对应的处理函数,pre_config, pre_config, post_config和child_init是启动钩子,它们是在服务器启动时调用,处理程序钩子是请求挂钩,它是在服务器请求是调用,通过这些钩子,就可以通过Apache服务器启动PHP。

PHP与WEB服务器交互的案例分析