首先来张PHP的架构图:
什么SAPI?
SAPI的中文译作:服务器端应用编程接口。它负责PHP与其他应用交互数据。这里的其他应用可能是shell或者apache等等。常见的SAPI有:
CGI,Fast-cgi,CLI(for shell),isapi(for IIS),Embed(for c/c++)等等。
举例:当在Shell下(window下的command line)输入:php index.php 此时,由CLI这个SAPI负责将用户的请求处理。要定义一个SAPI,需要定义一个结构体。
CLI的SAPI结构如下:(/path/to/php-src/sapi/cli/php_cli.c)
结构体sapi_module_struct定义了当一个cli sapi启动所做的一些操作,下面我们来看看。
1:“cli"定义了当前sapi的名称,phpinfo函数将使用这个名称。
2:php_cli_startup,该函数的完整定义为
可以看到该函数将调用php_module_startup.这是一个PHP初始化函数(这部分参见:http://www.walu.cc/phpbook/1.3.md php生命周期)
3:php_module_shutdown_wrapper,函数的定义是:
只是简单的对php_module_shutdown()做了简单的包装
4:PHP对每个request做一些初始化,资源分配的事务,在这里对cli并没有相应的handler。但对于mod_php就不同了。他要在apache的pool中注册资源析构函数,申请空间,初始化环境变量等等。
5:sapi_cli_deactivate,收尾的工作。
6:sapi_cli_ub_write,提供给Zend刷新缓存的函数句柄,
sapi_cli_single_write函数将数据写入stdout中
7:sapi_cli_flush,
该函数调用了系统的fflush进行缓存区的刷新。
8:这部分能让Zend验证一个要执行的脚本文件state,判断权限。
9:getenv 获取环境变量 ,cli没有提供
10:php_error 错误处理函数,这个没得说。在哪里定义的还没找到。
11:sapi_cli_header_handler 这个是header()的时候调用,cli提供了一个空实现。简单的return 0;
12:sapi_cli_send_headers,这个函数将在真正发送header的时候调用。在cli中也提供了空实现
13:sapi_cli_send_header,单独发送一个header。同样的空实现
14:NULL 提供获取POST数据的函数handler,cli中没有POST的传递, read POST data
15:sapi_cli_read_cookies,不解释
16:sapi_cli_register_variables,该函数提供了一个注册变量的接口,可以在_SERVER中获得。(顺便一说,注意参数的传递,zval是zend variable哦。它是一个结构体,GC的实现跟变量里面的设计有关系。)
17:sapi_cli_log_message,这个用来输出错误信息的啦,在cli来说,将错误输出到stderr
18:获取请求时间Get request time
19:这个不懂Child terminate