SAPI 即 Server API ,是应用程序与外部程序的通讯协议。
在PHP源码的sapi目录下就是当前版本提供的SAPI列表:
apache2handler
cgi
embed
cli
litespeed
phpdbg
编译后你就会看到php, php-cgi, php-fpm三个可执行程序。
如果是在win环境下会看到php.exe, php-cgi.exe文件。
php
在cli模式下运行的程序,用来解释运行PHP代码。
php-cgi
实现了fastcgi协议的程序。当你使用phpstudy构建WNMP环境的时候,phpstudy它会启动一个php-cgi进程并监听9000端口,然后你需要
配置nginx的fastcgi_pass参数。如果觉得一个进程不够用,可以自己启动多个,使用命令
php-cgi.exe -b 127.0.0.1:9001 -c D:\phpStudy\PHPTutorial\php\php-7.2.1-nts\php.ini
php-fpm
fastcgi process manager 即用来管理fastcgi进程,php-fpm程序实现了fastcgi并可以优雅的管理多进程,因为php-cgi是单个的
进程,并发处理能力很弱,当然你也可以手动多开,但是依然难以管理,而fpm的出现主要是解决这个问题的,当然它不是简单的管理php-cgi
,而是重新实现了fastcgi协议并增加了很多管理功能,目前只有Linux环境可以用。
那么,如何知道当前PHP程序是运行在哪个SAPI下呢?
<?php
echo PHP_SAPI;
?>
分别通过nginx,apache,命令行访问;会依次返回 fpm-fcgi, apache2handler, cli。
或者
命令行下 php -i |grep API
Server API => Command Line Interface
web环境下
<?php
phpinfo();
?>
找到 Server API FPM/FastCGI
并且由此可以看出,在不同的运行模式下,查看phpinfo得到的信息是不一样的,因为php会根据当前模式优化默认配置以及php.ini的配置。
SAPI从使用场景来看大致有:
1、CLI(Command Line Interface),即命令行接口;
2、CGI(COmmon Gateway Interface);即通用网关接口,也就是要走网络通讯。
至于什么是cgi, fastcgi 不是这里要讨论的内容,可以移步 https://blog.csdn.net/raoxiaoya/article/details/103280995
那么为什么PHP要使用fastcgi呢,还搞出这么多运行模式?
为了配合apache服务器,实现了 apache2handler。
为了配合nginx服务器,实现了 fastcgi。
之前还有基于IIS的协议实现。
。。。。。。
究其原因,PHP是单线程的,这就决定了如果用PHP程序来作为web服务器,其并发能力有限,但是基于nginx+php-fpm架构,其瓶颈也在php-fpm进程,但是也正是因为这种架构才使得PHP在早些年得以发展起来,我们知道java开发的web应用就不需要实现fastcgi,它只需要配合nginx的负载均衡等功能即可;当然目前基于swoole的应用也不再需要fastcgi,与java服务一样的运行,但是如果swoole能早点出现,PHP就不是现在的局面了。
关于SAPI的实现细节可参考鸟哥的文章 https://www.laruence.com/2008/08/12/180.html