SAPI这里所说的PHP运行方式,其实是指SAPI(ServerApplicationProgrammingInterface,服务器应用程序编程端口)。SAPI为PHP提供了与外界通信的接口,PHP通过这个接口与其他应用程序进行交互。针对不同的应用场景,PHP也提供了多种不同的SAPI,常见的有:apache、apache2filter、apache2handler、cli、cgi、embed、fast-cgi、isapi等。php_sapi_name()—返回web服务器和PHP之间的接口类型。可能的返回值包括aolserver、apache、apache2filter、apache2handler、caudium、cgi(直到PHP5.3)、cgi-fcgi、cli、cli-server、continuity、embed、fpm-fcgi、isapi、litespeed、milter、nsapi、phttpd、pi3web、roxen、thttpd、tux和webjames。目前很多PHP内置的SAPI实现已经不再维护或者已经有些非主流。PHP社区目前正在考虑将一些SAPI移出代码库。社区对很多功能的考虑是,除非真的有必要,或者有些功能接近于非常通用,否则PECL库中都有。接下来,将描述五种更常见的操作模式。CLI模式CLI(CommandLineInterface),即命令行界面,默认会安装PHP。通过这个接口,可以在shell环境下与PHP进行交互。在终端输入php-v,会得到类似下图的结果(在安装PHP的前提下):因为CLI的存在,我们可以直接在终端命令行运行PHP脚本,就像使用shell和Python,不依赖于WEB服务器。比如Laravel框架中的Artisan命令行工具,其实就是一个PHP脚本,帮助我们快速构建Laravel应用。CGI模式CGI(CommonGatewayInterface,通用网关接口)是一种重要的互联网技术,它允许客户端从网络浏览器请求数据到网络服务器上执行的程序。CGI描述了在服务器和请求处理程序之间传输数据的标准。WEB服务器只是内容的分发者。比如Nginx,如果客户端请求/index.html,那么Nginx会在文件系统中找到这个文件,发送给浏览器,浏览器中分发静态数据;如果客户端现在请求/index.php,根据配置文件,Nginx知道这不是静态文件,需要去PHP解析器处理,然后简单处理后将请求传递给PHP解析器.Nginx会将哪些数据传递给PHP解析器?必须有url、查询字符串、POST数据和HTTP请求标头。那么,CGI就是一个协议,规定了传输哪些数据,以什么格式传递给后方处理请求。.CGI方式运行原理:当Nginx收到浏览器的/index.php请求时,会先创建一个对应的实现CGI协议的进程,这里是php-cgi(PHP解析器)。接下来php-cgi会解析php.ini文件,初始化执行环境,然后处理请求,将处理结果以CGI指定的格式返回,并退出进程。最后,Nginx将结果返回给浏览器。整个过程是一个Fork-And-Execute模式。当用户请求数非常大时,会占用大量的内存、CPU时间等系统资源,导致性能低下。因此,在使用CGI模式的服务器下,有多少个连接请求,就会有多少个CGI子进程,而子进程的重复加载是造成CGI性能低下的主要原因。CGI模式的优点是它完全独立于任何服务器,只是作为一个中介:为WEB服务器和脚本语言或完全独立的编程语言提供接口。它们通过CGI协议连线完成数据传输。这样做的好处是尽量减少它们之间的相关性,使它们更加独立和相互独立。CGI模式已经是比较老的模式了,这几年已经很少用了。FastCGI模式FastCGI(FastCommonGatewayInterface,快速通用网关接口)是交互式程序与Web服务器通信的一种协议。FastCGI是早期通用网关接口(CGI)的增强版本。FastCGI致力于减少Web服务器与CGI程序交互的开销,使服务器可以同时处理更多的网页请求。根据定义我们可以知道FastCGI也是一个协议。实现FastCGI协议的程序更像是一个常驻(long-live)的CGI协议程序。分叉一次需要时间。FastCGI模式运行原理:FastCGI进程管理器启动后,首先会解析php.ini文件,初始化执行环境,然后启动多个CGI协议解释器守护进程(可以看到多个php-cig或php-cgi.ini)。exe),等待WEB服务器的连接;当客户端请求到达WEB服务器时,FastCGI进程管理器会选择并连接到一个CGI解释器,WEB服务器会将CGI环境变量和标准输入发送给FastCGI子进程php-cgi;php-cgi子进程处理完成后,将标准输出和错误信息返回给WEB服务器;这时候php-cgi子进程会关闭连接,处理请求,然后继续等待处理来自下一个请求连接到FastCGI进程管理器的请求。FastCGI方式采用C/S结构,可以将WEB服务器和脚本分析服务器分开,同时在脚本分析服务器上启动一个或多个脚本分析守护进程。当WEB服务器每次遇到动态程序时,可以直接传递给FastCGI进程执行,然后将结果返回给浏览器。这种方式可以让WEB服务器独占处理静态请求或者将动态脚本服务器的结果返回给客户端,大大提高了整个应用系统的性能。另外,在CGI模式下,php-cgi更改php.ini配置后,需要重启php-cgi进程才能使新的php-ini配置生效,无法平滑重启。在FastCGI模式下,PHP-FPM可以通过生成新的子进程实现php.ini修改后的平滑重启。PHP-FPM(PHP-FastCGIProcessManager)是一个用PHP语言实现FastCGI协议的进程管理器。它由AndreiNigmatulin编写和实现,并已正式包含在PHP中并集成到内核中。FastCGI模式的优点:在稳定性方面,FastCGI模式使用独立的进程池来运行CGI协议程序。如果单个进程挂掉,系统很容易将其丢弃,然后重新分配一个新的进程来运行逻辑;从安全的角度和性能的角度来看,FastCGI模式支持分布式计算。FastCGI程序与宿主Server完全独立,FastCGI程序挂掉不会影响Server;从性能上看,FastCGI模式将动态逻辑的处理从Server中分离出来,繁重的IO处理仍然留给了宿主Server,让宿主Server的IO可以全心全意的处理。对于一个普通的动态网页来说,可能只有一小部分逻辑处理,还有大量的图片等静态图像。FastCGI方式是目前PHP主流的WEB服务运行方式。性能高效可靠,推荐大家使用。模块模式的PHP通常与Apache服务器配对,形成LAMP的配套运行环境。将PHP作为子模块集成到Apache中就是Module模式。Apache中常见的配置如下:LoadModulephp5_modulemodules/mod_php5.so这里使用了LoadModule命令。该命令的第一个参数是模块的名称,可以在模块实现的源代码中找到。第二个选项是模块所在的路径。如果需要在服务器运行时加载模块,可以向服务器发送信号HUP或AP_SIG_GRACEFUL。收到信号后,Apache将重新加载模块,而无需重新启动服务器。该模块在Apache启动时启动,以通过在apache2中注册的ap_hook_post_config挂钩接受对PHP文件的请求。例如,当客户端访问一个PHP文件时,Apache调用php5_module来解析PHP脚本。每次Apache收到请求时,它都会生成一个进程来连接到PHP以完成请求。在Module模式下,有时候因为PHP是作为一个模块编译到Apache中的,所以出现问题的时候很难定位是PHP还是Apache的问题。过去,由于其丰富的模块和功能,企业往往将Apache作为WEB服务器,因此以Module模式运行的PHP+Apache的组合非常普遍。近年来,随着异步事件驱动和高性能Nginx服务器的兴起,市场份额快速增长。以FastCGI方式运行的PHP+Nginx组合,性能更优,有追赶Apache的趋势。ISAPI模式ISAPI(InternetServerApplicationProgramInterface)是微软公司提供的一套用于Internet服务的API接口。一个ISAPIDLL可以在被一个用户请求激活后留在内存中,等待用户的另一个请求,也可以在一个DLL中设置多个用户请求处理函数。另外,ISAPI的DLL应用程序和WEB服务器在同一个进程中,效率明显高于CGI。由于微软的排他性,它只能在Windows环境下运行。很少用到,这里就不详细介绍了。以上内容整理自网络,参考文章:SAPI概览PHP运行方式PHP运行方式CGI、FastCGI与PHP-FPM关系图想不通FastCgi与PHP-fpm是什么关系
