SAPI: Server Application Programming Interface 服务器端应用编程端口。先看一张php模块图。
从图中可以看出,各种应用都是通过对应的SAPI与php进行交互的,SAPI相当于一个接口,使得php的核心实现不用关心各个应用交互的细节。虽然通过Web服务器和命令行程序执行脚本看起来很不一样,实际上它们的工作流程是一样的。
在php的源代码sapi目录下有多种sapi的具体实现,比如cgi、cli、apache、fpm等。SAPI中最重要的一个数据结构就是_sapi_module_struct
,定义在/main/SAPI.h中。
不同的SAPI就是用不同的参数实例化_sapi_module_struct来实习的,下面我们分别简单分析一些cgi SAPI和cli SAPI的源代码,力求对SAPI有些更深入的理解。
1.cgi模式
cgi模式下,_sapi_module_struct的实例定义在cgi_main.c中。
下面分析 char *(*read_cookies)(TSRMLS_D)
在cgi模式下的实现:sapi_cgi_read_cookies。其中sapi_cgi_read_cookies的源码片段如下:
可以看到,cgi模式下的char *(*read_cookies)(TSRMLS_D)
最终为从环境变量中读取HTTP_COOKIE。
2.cli 模式
cgi模式下,_sapi_module_struct的实例定义在php_cli.c
下面分析 char *(*read_cookies)(TSRMLS_D)
在cli模式下的实现:sapi_cli_read_cookies。其中sapi_cli_read_cookies的源码片段如下:
可以看到,cgi模式下的char *(*read_cookies)(TSRMLS_D)
最终为直接返回NULL,因为cli模式下不存在用户cookies信息。
通过上面的cgi和cli模式下read_cookies的不同实现,可以看出sapi确实对下层php屏蔽了交互细节,当下层php核心要读取用户cookies时,只需要通过sapi_module_struct->read_cookies,而不需要关注上层应用的交互细节。
that right! 这就是SAPI的作用。