必须手动启动php-cgi.exe并确保其监听地址与nginx.conf中fastcgi_pass严格一致,否则nginx无法连接导致502错误;需用runhiddenconsole后台运行,且php.ini中cgi.force_redirect=0、cgi.fix_pathinfo=1、extension_dir和date.timezone等关键项必须正确配置。

php-cgi.exe 必须手动启动,且监听地址必须和 nginx.conf 里 fastcgi_pass 的值严格一致——这是 Windows 下 502 Bad Gateway 最常见的根源。
怎么让 nginx 找到 php-cgi 并不报 502
Windows 不像 Linux 那样能用 systemd 或 init 管理进程,php-cgi.exe 是个命令行程序,不加参数直接双击会闪退,必须用批处理或工具包裹后持续运行。
常见错误现象:
- 浏览器访问
.php文件返回502 Bad Gateway -
nginx -t检查配置通过,但日志里反复出现connect() failed (10061: No connection could be made)
实操建议:
- 不要用
php.exe,必须用php-cgi.exe(NTS 版本才带这个可执行文件) - 启动命令形如:
php-cgi.exe -b 127.0.0.1:9000,端口必须和nginx.conf中fastcgi_pass 127.0.0.1:9000完全一致 - 推荐用
RunHiddenConsole.exe包裹,避免窗口弹出又关闭:RunHiddenConsole.exe php-cgi.exe -b 127.0.0.1:9000 - 若端口被占用(比如另一个 php-cgi 正在跑),改端口的同时务必同步改
nginx.conf
php.ini 里哪些配置项不设就肯定挂
Windows 下 PHP 要跑通,不是“开了扩展就行”,而是几个关键开关必须显式设置,否则 Nginx 请求进来后 PHP 直接拒绝处理。
最容易漏掉的三项:
-
cgi.fix_pathinfo=1—— 不设会导致SCRIPT_FILENAME解析错乱,Nginx 传过来的路径变成空或错误路径 -
extension_dir="C:/php/ext"—— 必须是绝对路径,且指向真实存在的ext目录;路径中斜杠用/或\,别混用 -
date.timezone="Asia/Shanghai"—— 不设会在错误日志里刷满警告,虽不影响运行,但干扰排查
注意:cgi.force_redirect 在 Windows + Nginx 场景下应设为 0,设成 1 会导致所有请求被拦截并返回 404。
nginx.conf 里 location ~ .php$ 的坑在哪
这段配置看着简单,但 Windows 下最常出问题的是 SCRIPT_FILENAME 的拼接逻辑。Nginx 默认不自动补全根路径,靠你手工写对。
正确写法(必须):
location ~ .php$ {
root C:/www;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
错误高发点:
- 把
$document_root$fastcgi_script_name写成$script_filename(这个变量 Nginx 不提供,PHP 也收不到) - 在
location块里漏写root,导致$document_root为空,最终SCRIPT_FILENAME变成C:/www/后面没东西 - 多个
server块共用一套fastcgi_params,但其中某条fastcgi_param被覆盖或遗漏
为什么测试 phpinfo() 成功了,mysqli 却连不上 MySQL
这和 Nginx、PHP 配置无关,纯属 MySQL 认证插件不兼容。PHP 8.0+ 默认用 mysql_native_password,而 MySQL 8.0+ 新建用户默认用 caching_sha2_password。
现象:
-
phpinfo()页面正常显示 - 代码里
new mysqli(...)报错:mysqli_connect(): The server requested authentication method unknown to the client [caching_sha2_password]
解决方法(选其一):
- 重置 MySQL 用户认证方式:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 或在 PHP 连接时显式指定驱动:
mysqli_real_connect($link, $host, $user, $pass, $db, $port, null, MYSQLI_CLIENT_SSL);(不治本) - 更稳妥的做法:安装 MySQL 5.7 或启用兼容模式,避免版本错配
真正麻烦的从来不是装上,而是各组件默认行为之间的隐性冲突——比如 php-cgi.exe 不后台驻留、cgi.fix_pathinfo 默认关着、MySQL 认证方式悄悄升级……这些点不手动掰正,环境永远差一口气。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











