国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

如何通過(guò)mod_php5支持PHP

原創(chuàng) 2016-11-21 10:29:01 539
摘要:Apache對(duì)PHP的支持是通過(guò)Apache的模塊mod_php5來(lái)支持的。如果希望Apache支持PHP的話,在./configure步驟需要指定--with-apxs2=/usr/local/apache2/bin/apxs 表示告訴編譯器通過(guò)Apache的mod_php5/apxs來(lái)提供對(duì)PHP5的解析。在最后一步make install的時(shí)候我們會(huì)看到將動(dòng)態(tài)鏈接庫(kù)libphp5.

Apache對(duì)PHP的支持是通過(guò)Apache的模塊mod_php5來(lái)支持的。如果希望Apache支持PHP的話,在./configure步驟需要指定--with-apxs2=/usr/local/apache2/bin/apxs 表示告訴編譯器通過(guò)Apache的mod_php5/apxs來(lái)提供對(duì)PHP5的解析。

在最后一步make install的時(shí)候我們會(huì)看到將動(dòng)態(tài)鏈接庫(kù)libphp5.so(Apache模塊)拷貝到apache2的安裝目錄的modules目錄下,并且還需要在httpd.conf配置文件中添加LoadModule語(yǔ)句來(lái)動(dòng)態(tài)將libphp5.so 模塊加載進(jìn)來(lái),從而實(shí)現(xiàn)Apache對(duì)php的支持。

由于該模式實(shí)在太經(jīng)典了,因此這里關(guān)于安裝部分不準(zhǔn)備詳述了,相對(duì)來(lái)說(shuō)比較簡(jiǎn)單。我們知道nginx一般包括兩個(gè)用途HTTP Server和Reverse Proxy Server(反向代理服務(wù)器)。在前端可以部署nginx作為reverse proxy server,后端布置多個(gè)Apache來(lái)實(shí)現(xiàn)集群系統(tǒng)server cluster架構(gòu)的。

因此,實(shí)際生產(chǎn)中,我們?nèi)耘f能夠保留Apache+mod_php5的經(jīng)典App Server,而僅僅使用nginx來(lái)當(dāng)做前端的reverse proxy server來(lái)實(shí)現(xiàn)代理和負(fù)載均衡。 因此,建議nginx(1個(gè)或者多個(gè))+多個(gè)apache的架構(gòu)繼續(xù)使用下去。

Apache2的mod_php5模塊包括sapi/apache2handler和sapi/apache2filter兩個(gè)目錄 在apache2_handle/mod_php5.c文件中,模塊定義的相關(guān)代碼如下:

AP_MODULE_DECLARE_DATA module php5_module = {
    STANDARD20_MODULE_STUFF,
        /* 宏,包括版本,小版本,模塊索引,模塊名,下一個(gè)模塊指針等信息,其中模塊名以__FILE__體現(xiàn) */
    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 */
    php_dir_cmds,           /* 模塊定義的所有的指令 */
    php_ap2_register_hook
        /* 注冊(cè)鉤子,此函數(shù)通過(guò)ap_hoo_開(kāi)頭的函數(shù)在一次請(qǐng)求處理過(guò)程中對(duì)于指定的步驟注冊(cè)鉤子 */
};

它所對(duì)應(yīng)的是Apache的module結(jié)構(gòu),module的結(jié)構(gòu)定義如下:

typedef struct module_struct module;
struct module_struct {
    int version;
    int minor_version;
    int module_index;
    const char *name;
    void *dynamic_load_handle;
    struct module_struct *next;
    unsigned long magic;
    void (*rewrite_args) (process_rec *process);
    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;
    void (*register_hooks) (apr_pool_t *p);
}

上面的模塊結(jié)構(gòu)與我們?cè)趍od_php5.c中所看到的結(jié)構(gòu)有一點(diǎn)不同,這是由于STANDARD20_MODULE_STUFF的原因, 這個(gè)宏它包含了前面8個(gè)字段的定義。STANDARD20_MODULE_STUFF宏的定義如下:

/** Use this in all standard modules */
#define STANDARD20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \
                MODULE_MAGIC_NUMBER_MINOR, \
                -1, \
                __FILE__, \
                NULL, \
                NULL, \
                MODULE_MAGIC_COOKIE, \
                                NULL      /* rewrite args spot */

在php5_module定義的結(jié)構(gòu)中,php_dir_cmds是模塊定義的所有的指令集合,其定義的內(nèi)容如下:

const command_rec php_dir_cmds[] =
{
    AP_INIT_TAKE2("php_value", php_apache_value_handler, NULL,
        OR_OPTIONS, "PHP Value Modifier"),
    AP_INIT_TAKE2("php_flag", php_apache_flag_handler, NULL,
        OR_OPTIONS, "PHP Flag Modifier"),
    AP_INIT_TAKE2("php_admin_value", php_apache_admin_value_handler,
        NULL, ACCESS_CONF|RSRC_CONF, "PHP Value Modifier (Admin)"),
    AP_INIT_TAKE2("php_admin_flag", php_apache_admin_flag_handler,
        NULL, ACCESS_CONF|RSRC_CONF, "PHP Flag Modifier (Admin)"),
    AP_INIT_TAKE1("PHPINIDir", php_apache_phpini_set, NULL,
        RSRC_CONF, "Directory containing the php.ini file"),
    {NULL}
};

這是mod_php5模塊定義的指令表。它實(shí)際上是一個(gè)command_rec結(jié)構(gòu)的數(shù)組。 當(dāng)Apache遇到指令的時(shí)候?qū)⒅鹨槐闅v各個(gè)模塊中的指令表,查找是否有哪個(gè)模塊能夠處理該指令, 如果找到,則調(diào)用相應(yīng)的處理函數(shù),如果所有指令表中的模塊都不能處理該指令,那么將報(bào)錯(cuò)。 如上可見(jiàn),mod_php5模塊僅提供php_value等5個(gè)指令。

php_ap2_register_hook函數(shù)的定義如下:

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,handler和child_init 4個(gè)掛鉤以及對(duì)應(yīng)的處理函數(shù)。 其中pre_config,post_config,child_init是啟動(dòng)掛鉤,它們?cè)诜?wù)器啟動(dòng)時(shí)調(diào)用。 handler掛鉤是請(qǐng)求掛鉤,它在服務(wù)器處理請(qǐng)求時(shí)調(diào)用。其中在post_config掛鉤中啟動(dòng)php。 它通過(guò)php_apache_server_startup函數(shù)實(shí)現(xiàn)。php_apache_server_startup函數(shù)通過(guò)調(diào)用sapi_startup啟動(dòng)sapi, 并通過(guò)調(diào)用php_apache2_startup來(lái)注冊(cè)sapi module struct(此結(jié)構(gòu)在本節(jié)開(kāi)頭中有說(shuō)明), 最后調(diào)用php_module_startup來(lái)初始化PHP, 其中又會(huì)初始化ZEND引擎,以及填充zend_module_struct中 的treat_data成員(通過(guò)php_startup_sapi_content_types)等。

到這里,我們知道了Apache加載mod_php5模塊的整個(gè)過(guò)程,可是這個(gè)過(guò)程與我們的SAPI有什么關(guān)系呢? mod_php5也定義了屬于Apache的sapi_module_struct結(jié)構(gòu):

static sapi_module_struct apache2_sapi_module = {
"apache2handler",
"Apache 2.0 Handler",

php_apache2_startup,                /* startup */
php_module_shutdown_wrapper,            /* shutdown */

NULL,                       /* activate */
NULL,                       /* deactivate */

php_apache_sapi_ub_write,           /* unbuffered write */
php_apache_sapi_flush,              /* flush */
php_apache_sapi_get_stat,           /* get uid */
php_apache_sapi_getenv,             /* getenv */

php_error,                  /* error handler */

php_apache_sapi_header_handler,         /* header handler */
php_apache_sapi_send_headers,           /* send headers handler */
NULL,                       /* send header handler */

php_apache_sapi_read_post,          /* read POST data */
php_apache_sapi_read_cookies,           /* read Cookies */

php_apache_sapi_register_variables,
php_apache_sapi_log_message,            /* Log message */
php_apache_sapi_get_request_time,       /* Request Time */
NULL,                       /* Child Terminate */

STANDARD_SAPI_MODULE_PROPERTIES
};

這些方法都專屬于Apache服務(wù)器。以讀取cookie為例,當(dāng)我們?cè)贏pache服務(wù)器環(huán)境下,在PHP中調(diào)用讀取Cookie時(shí), 最終獲取的數(shù)據(jù)的位置是在激活SAPI時(shí)。它所調(diào)用的方法是read_cookies。

SG(request_info).cookie_data = sapi_module.read_cookies(TSRMLS_C);

對(duì)于每一個(gè)服務(wù)器在加載時(shí),我們都指定了sapi_module,而Apache的sapi_module是apache2_sapi_module。 其中對(duì)應(yīng)read_cookies方法的是php_apache_sapi_read_cookies函數(shù)。 這也是定義SAPI結(jié)構(gòu)的理由:統(tǒng)一接口,面向接口的編程,具有更好的擴(kuò)展性和適應(yīng)性。


發(fā)佈手記

熱門(mén)詞條