SAPI: Server abstraction API,研究过PHP架构的同学应该知道这个东东的重要性,它提供了一个接口,使得PHP可以和其他应用进行交互数据。 本文不会详细介绍每个PHP的SAPI,只是针对最简单的CGI SAPI,来说明SAPI的机制。
首先,我们来看看PHP的架构图:
图1 PHP Architecture
SAPI提供了一个和外部通信的接口, 对于PHP5.2,默认提供了很多种SAPI, 常见的给apache的mod_php5,CGI,给IIS的ISAPI,还有Shell的CLI,本文就从CGI SAPI入手 ,介绍SAPI的机制。 虽然CGI简单,但是不用担心,它包含了绝大部分内容,足以让你深刻理解SAPI的工作原理。
要定义个SAPI,首先要定义个sapi_module_struct, 查看 PHP-SRC/sapi/cgi/cgi_main.c:
*/static sapi_module_struct cgi_sapi_module = {#if PHP_FASTCGI "cgi-fcgi", /* name */ "CGI/FastCGI", /* pretty name */#else "cgi", /* name */ "CGI", /* pretty name */#endif php_cgi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ sapi_cgi_deactivate, /* deactivate */ sapi_cgibin_ub_write, /* unbuffered write */ sapi_cgibin_flush, /* flush */ NULL, /* get uid */ sapi_cgibin_getenv, /* getenv */ php_error, /* error handler */ NULL, /* header handler */ sapi_cgi_send_headers, /* send headers handler */ NULL, /* send header handler */ sapi_cgi_read_post, /* read POST data */ sapi_cgi_read_cookies, /* read Cookies */ sapi_cgi_register_variables, /* register server variables */ sapi_cgi_log_message, /* Log message */ NULL, /* Get request time */ STANDARD_SAPI_MODULE_PROPERTIES};
这个结构,包含了一些常量,比如name, 这个会在我们调用php_info()的时候被使用。一些初始化,收尾函数,以及一些函数指针,用来告诉Zend,如何获取,和输出数据。
1. php_cgi_startup, 当一个应用要调用PHP的时候,这个函数会被调用,对于CGI来说,它只是简单的调用了PHP的初始化函数:
static int php_cgi_startup(sapi_module_struct *sapi_module){ if (php_module_startup(sapi_module, NULL, 0) == FAILURE) { return FAILURE; } return SUCCESS;}
2. php_module_shutdown_wrapper , 一个对PHP关闭函数的简单包装。只是简单的调用php_module_shutdown;
3. PHP会在每个request的时候,处理一些初始化,资源分配的事务。这部分就是activate字段要定义的,从上面的结构我们可以看出,对于CGI来说,它并没有提供初始化处理句柄。对于mod_php来说,那就不同了,他要在apache的pool中注册资源析构函数, 申请空间, 初始化环境变量,等等等等。
新闻热点
疑难解答