fastcgi是语言无关的二进制协议规范,php 7.2.33通过sapi/cgi/下的fastcgi.c等文件实现sapi层通信,以php-cgi进程解析record、执行脚本并按协议返回响应,区别于具备进程管理能力的php-fpm。

PHP 7.2.33 的 FastCGI 协议实现,核心不在“协议本身”,而在于它如何通过 php-cgi(即 SAPI 层的 fastcgi SAPI)与 Web 服务器(如 Nginx、IIS)通信。FastCGI 是一个**语言无关的二进制协议规范**,PHP 并不“实现协议标准文档”,而是通过其 fastcgi SAPI 模块严格遵循该协议收发数据包,完成请求解析、执行、响应返回的整套流程。
FastCGI 在 PHP 源码中的落点:fastcgi SAPI
PHP 源码中,FastCGI 支持由 SAPI(Server Application Programming Interface)子系统提供,路径为:php-src/sapi/cgi/(注意:不是 sapi/fpm/ —— 那是 PHP-FPM 专用的独立实现)。
关键文件包括:
-
sapi/cgi/fastcgi.c:核心协议逻辑,定义 FastCGI record 结构体(fcgi_record)、读写 record 的函数(read_record()、write_record())、record 类型枚举(如FCGI_BEGIN_REQUEST、FCGI_STDIN、FCGI_STDOUT等) -
sapi/cgi/cgi_main.c:主循环入口,调用fcgi_accept_request()接收并解析完整 FastCGI 请求包,填充SG(request_info),再进入 PHP 执行阶段 -
sapi/cgi/php_cgi.h:声明 FastCGI 相关宏、结构和函数原型
协议交互的关键步骤(源码级行为)
当 Web 服务器(如 Nginx)发起一次 FastCGI 请求时,PHP 7.2.33 的 php-cgi 进程会按如下顺序处理:
- 监听 socket(Unix domain socket 或 TCP port),等待
accept()新连接 - 循环调用
fcgi_accept_request():从 socket 读取字节流,按 FastCGI 协议格式逐个解析 record —— 先读 8 字节 header,再根据contentLength读取 payload - 将
FCGI_PARAMSrecord 中的键值对(如SCRIPT_FILENAME、QUERY_STRING、REQUEST_METHOD)解码后存入SG(sapi_headers).headers和SG(request_info)结构体 - 执行
php_execute_script()运行目标 PHP 脚本;期间所有echo、print输出被暂存到输出缓冲区 - 将响应头(通过
Header:或Set-Cookie:等)和响应体,按 FastCGI 协议打包成FCGI_STDOUT和FCGI_END_REQUESTrecord,写回 socket
与 PHP-FPM 的本质区别
PHP 7.2.33 自带的 php-cgi 是一个单进程、阻塞式、无管理能力的 FastCGI 实现:
- 每次启动只服务一个连接(除非配合 spawn-fcgi 等 wrapper)
- 不内置进程管理(无 master/worker 模型、无平滑重启、无动态伸缩)
- 不支持慢日志、动态子进程配置、优雅 reload 等运维功能
而 php-fpm 是一个独立的、增强型 FastCGI 守护进程,它内部也使用同一套 sapi/cgi/ 协议逻辑(共享 fastcgi.c),但封装了完整的进程模型、信号处理、配置解析、监控接口等 —— 它才是生产环境推荐的方式。
编译启用 FastCGI SAPI 的要点
从源码编译 PHP 7.2.33 并启用 FastCGI,需在 ./configure 时明确指定:
-
--enable-fastcgi(PHP 7.2 已默认开启,但显式声明更稳妥) -
--disable-cli可选(若只用于 FastCGI 场景) -
--without-apxs2(避免混入 Apache 模块)
编译完成后,生成的可执行文件是 php-src/sapi/cgi/php-cgi,而非 php(CLI SAPI)。运行它时需传入 FastCGI 参数,例如:
表示以 TCP 方式监听 9000 端口,等待 Web 服务器连接。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











