PHP内核之Apache的PHP模块启动

原创 2016年08月28日 21:29:38

首先,我们必须知道所有的apache module都必须是这个结构体,其定义结构如下(以PHP模块为例):

AP_MODULE_DECLARE_DATA module php5_module = {
	STANDARD20_MODULE_STUFF,
	create_php_config,		/* create per-directory config structure */
	merge_php_config,		/* merge per-directory config structures */
	NULL,					/* create per-server config structure */
	NULL,					/* merge per-server config structures */
	/* 上面4项都是定义httpd.conf中命令的作用的 */
	php_dir_cmds,			/* command apr_table_t */ * 定义在httpd.conf中添加的命令,和各命令的处理函数 *//
	php_ap2_register_hook	/* register hooks */ /* hooks,定义什么时候执行我们这个 module的相关函数 */
};

STANDARD20_MODULE_STUFF这个宏是必须的,这个宏在经过扩展以后,可以为编译后的模块载入服务器构建提供版本信息,

在PHP的模块中,

create_php_config函数创建目录配置结构,

merge_php_config合并目录配置结构,

php_dir_cmds函数为模块配置相关指令,

php_ap2_register_hook 注册模块的钩子程序,

在这里主要关注的是php_ap2_register_hook.这里定义的一些回调方法,会在Apache启动的时候直接调用。 

查看php-5.5.12/sapi/apache2handler/sapi_apache2.c文件:

void php_ap2_register_hook(apr_pool_t *p)
{
	ap_hook_pre_config(php_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
	ap_hook_post_config(php_apache_server_startup, NULL, NULL, APR_HOOK_MIDDLE);
	ap_hook_handler(php_handler, NULL, NULL, APR_HOOK_MIDDLE);
	ap_hook_child_init(php_apache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
}


其中 

pre_config,  post_config, child_init 是启动挂钩,在服务器启动时调用
handler是请求挂钩,在服务器处理请求时调用


其中

在 post_config 挂钩中启动php  
post_config通过php_apache_server_startup函数实现, 


php_apache_server_startup函数也在同一个文件里面实现:

static int
php_apache_server_startup(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
	void *data = NULL;
	const char *userdata_key = "apache2hook_post_config";

	/* Apache will load, unload and then reload a DSO module. This
	 * prevents us from starting PHP until the second load. */
	apr_pool_userdata_get(&data, userdata_key, s->process->pool);
	if (data == NULL) {
		/* We must use set() here and *not* setn(), otherwise the
		 * static string pointed to by userdata_key will be mapped
		 * to a different location when the DSO is reloaded and the
		 * pointers won't match, causing get() to return NULL when
		 * we expected it to return non-NULL. */
		apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, s->process->pool);
		return OK;
	}

	/* Set up our overridden path. */
	if (apache2_php_ini_path_override) {
		apache2_sapi_module.php_ini_path_override = apache2_php_ini_path_override;
	}
#ifdef ZTS
	tsrm_startup(1, 1, 0, NULL);
#endif
	sapi_startup(&apache2_sapi_module);
	apache2_sapi_module.startup(&apache2_sapi_module);
	apr_pool_cleanup_register(pconf, NULL, php_apache_server_shutdown, apr_pool_cleanup_null);
	php_apache_add_version(pconf);

	return OK;
}

在这个函数里会调用apache2_sapi_module.startup函数,它最终调用的是php_module_startup函数,这个函数会初始化若干全局变量,若干常量,Zend引擎和核心组件,解析php.ini,全局操作函数,静态模块和共享模块(MINIT),同时还会禁用一些函数和类

这个函数具体介绍可以查看前一篇博文 PHP内核之SAPI:Apache2 SAPI分析

这就完成从apache启动之后,至PHP的初始化和环境准备了。


版权声明:本文为博主原创文章,未经博主允许不得转载。

php在apache中运行模式

php在apache中一共有三种工作方式:CGI模式、FastCGI模式、Apache 模块DLL) 以下分别比较: 1. CGI模式与模块模式比较: php在apache中两种工作...
  • wang55812526
  • wang55812526
  • 2014年08月13日 10:25
  • 3234

从源码安装apache httpd,并加载对php的支持

要完成如题所述目标,分两步走:首先从源码安装apache httpd,然后加载对php的支持。 一、从源码安装apache httpd 1、首先下载最新的httpd包,这里使用的是httpd-2.4....
  • DSLZTX
  • DSLZTX
  • 2015年10月12日 18:10
  • 5691

部署两套apache-httpd,php不同版本,添加php模块

背景介绍: 两套php的web应用,A 应用需要php7版本,B应用需要php5。其中B需要mbstring功能 1. 安装两个apache-httpd  注意1> 指定两个不同安装目录...
  • zhuchunyan_aijia
  • zhuchunyan_aijia
  • 2017年01月12日 11:28
  • 1213

如何向已经安装好的apache添加一个模块

转载:http://blog.sina.com.cn/s/blog_4dd475390102dte2.html http://www.apache.org/dist/httpd/ ma...
  • forest_boy
  • forest_boy
  • 2013年05月10日 10:29
  • 4479

深入PHP内核(转)

from: http://www.csdn.net/article/2014-09-26/2821885-exploring-of-the-php-2
  • longxibendi
  • longxibendi
  • 2014年09月26日 22:09
  • 1694

开启Mac自带apache和PHP开发环境

一、开启自带apache 在Terminal(终端)中输入 sudo apachectl start 上面代码功能是启动apache,在浏览器中输入http://localhost,你能看到 “...
  • yh_campus
  • yh_campus
  • 2016年01月11日 14:28
  • 7386

PHP架构-PHP内核

http://blog.areawebsolutions.com/php-architecture-the-php-core.html/comment-page-1
  • iefreer
  • iefreer
  • 2013年11月01日 18:58
  • 5151

Php与Apache的三种结合方式以及各自优缺点

httpd与php的结合方式: 如果网站的访问量很小,同一时间仅仅处理单个请求,那么各种结合方式的特点并不能很好的体现。这里我们仅考虑在高访问量、高并发情况下各种结合方式的优缺点。 CGI...
  • sinat_22991367
  • sinat_22991367
  • 2017年06月18日 14:49
  • 941

php在apache中三种工作方式:CGI模式、FastCGI模式、Apache 模块DLL 的区别

一、 php在apache中一共有三种工作方式:CGI模式、FastCGI 、FastCGI是什么?  FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行 为是将CGI解释器进程保持在内...
  • u010187139
  • u010187139
  • 2015年07月11日 11:18
  • 2433

Apache使用fcgid模块配置多个PHP版本共存

因为涉及多个时期开发的项目维护,每个项目使用的PHP版本都不同,想要在本地开发并调试就非常麻烦了,必须得想办法同时使用多个PHP版本才行于是总结了下面方法做个记录,apache 用的不多,只是本地开发...
  • zsjangel
  • zsjangel
  • 2017年01月03日 16:24
  • 2514
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PHP内核之Apache的PHP模块启动
举报原因:
原因补充:

(最多只允许输入30个字)