Apache 并不直接执行 PHP,它通过 mod_proxy_fcgi 或 mod_fastcgi,把 HTTP 请求封装成 FastCGI 请求,发送给 PHP-FPM 进程池,由 PHP-FPM 执行脚本并返回结果,Apache 再把响应发给浏览器。
背景
- PHP-FPM 只是 PHP 脚本的执行器/进程池,它不能直接接收 HTTP 请求。
- Apache 作为 HTTP 服务器,需要把 .php 文件请求交给 PHP-FPM 处理,然后再把结果返回给客户端。
- 通信协议:使用 FastCGI 协议(类似 RPC / 请求-响应协议)进行交互。
Apache + PHP-FPM 的典型配置方式
在 Apache 中有两种方式:
mod_php(传统方式,PHP 直接嵌入 Apache,PHP-FPM 不用)
mod_proxy_fcgi + PHP-FPM(现代高性能方式,推荐)
这里我们讲 mod_proxy_fcgi + PHP-FPM。
配置示例
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
<FilesMatch \.php$>
# 将 PHP 请求代理到 PHP-FPM
SetHandler “proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost/”
</FilesMatch>
</VirtualHost>
说明:
proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost/
- 使用 Unix Socket 连接 PHP-FPM(也可以用 TCP,例如 127.0.0.1:9000)
- fcgi:// 表示 FastCGI 协议
Apache 遇到 .php 文件 → 生成 FastCGI 请求 → 发送到 PHP-FPM
TCP 方式示例
<FilesMatch \.php$>
SetHandler “proxy:fcgi://127.0.0.1:9000”
</FilesMatch>
- PHP-FPM 监听 127.0.0.1:9000 TCP 端口
- Apache 通过 TCP 发送 FastCGI 请求
请求流程图
客户端浏览器
│
▼
Apache HTTP Server
│
│ 生成 FastCGI 请求
▼
PHP-FPM 进程池
│ 选择空闲 PHP 进程执行脚本
▼
执行 PHP 脚本
│ 输出响应
▼
Apache 收到结果
│
▼
返回给客户端
关键点
- Apache 通过 mod_proxy_fcgi 将 HTTP 请求转换为 FastCGI 请求
- PHP-FPM 是一个 进程池,空闲的进程拿到请求后执行
- 执行结束 → 输出发送给 Apache → Apache 返回给客户端
好处
- HP-FPM 进程池可以独立管理进程数量、重启策略
- Apache 不需要每个请求都 fork PHP 进程
- 性能和稳定性更高
FastCGI 协议特点
二进制协议,比 CGI 更高效
支持 keep-alive 连接(一个 PHP-FPM 进程可以连续处理多个请求)
通过 环境变量传递请求信息(SCRIPT_FILENAME、QUERY_STRING、REQUEST_METHOD 等)