跳转到内容

Windows 上 Nginx + PHP FastCGI:没有 php-fpm,别幻想

核验于 1 分钟阅读

把 php-cgi 作为 FastCGI 监听器,配置 Nginx 的 SCRIPT_FILENAME 与 fix_pathinfo,并理解为什么 IIS FastCGI 往往更适合 Windows。

测试环境Standard / Datacenter · 版本号 26100.33650 · x64
E1
版本号
26100.33650
版本
Standard / Datacenter
架构
x64
支持
文档(E1)
证据
E1官方文档
核验日期
2026-10-29
页面类型
任务

Nginx 不会自己拉起 PHP 工作进程。Windows 上你先启动 php-cgi.exe 作为 FastCGI 监听器,再让 Nginx 指过去:

终端窗口
C:\PHP\8.4\php-cgi.exe -b 127.0.0.1:9000 -c C:\PHP\8.4\php.ini

然后:

location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}

Windows 没有官方 php-fpm。指南让你在 Windows 装 php-fpm,要么是第三方构建,要么把 FastCGI 和 FPM 混了。

server {
listen 8084;
server_name php.local;
root C:/sites/php;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_pass 127.0.0.1:9000;
fastcgi_read_timeout 60s;
}
}

SCRIPT_FILENAME 是最容易漏的参数。没有它,PHP-CGI 报 “No input file specified” 或空白页。

cgi.fix_pathinfo=0
fastcgi.impersonate=1
date.timezone=UTC
expose_php=Off
display_errors=Off
log_errors=On

cgi.fix_pathinfo=0 加 try_files/=404,可以避免不存在的 .php 路径被交给 PHP-CGI。它不是上传校验的替代。

PHP-CGI 是要你保活的进程:

  • 用 WinSW/NSSM 或带重启的计划任务;
  • 设 PHP_FCGI_MAX_REQUESTS(如 500)让 worker 回收;
  • stderr/stdout 日志放在 Web 根之外;
  • 监控监听器(Test-NetConnection 127.0.0.1 9000);
  • 不要在同一 9000 启动第二个监听器。

纯 Windows 服务器,IIS FastCGI 通常比手包 php-cgi 更能管好 PHP;已经标准化 Nginx 或需要它的配置模型时,再用 Nginx+PHP。

终端窗口
& C:\PHP\8.4\php-cgi.exe -v
Test-NetConnection 127.0.0.1 -Port 9000
Set-Content C:\sites\php\info.php '<?php phpinfo();' -Encoding ASCII
curl.exe -I -H "Host: php.local" http://127.0.0.1:8084/info.php

测完删 info.php。

Nginx+PHP 为 E1。实验室装了 PHP 8.4.27 并验证 IIS FastCGI,但没有把 php-cgi 放到 Nginx 后面。Nginx 配置是下一步验证,不是已复现声明。

来源