ThinkPHP等框架访问/xxx返回404而/index.php/xxx可用,是伪静态未生效:Nginx未将请求转发至index.php,而是直接查找物理路径;根本原因在于缺少try_files $uri $uri/ /index.php?$query_string;或等效重写规则,且需确保root、SCRIPT_FILENAME、fastcgi_pass配置正确并重启服务。

Win7 下 Nginx + PHP 出现 404,90% 是路由重写或脚本路径没配对,不是 Laravel 或框架本身的问题。
为什么访问 /xxx 路由返回 404(但 /index.php/xxx 可用)
这是典型的「伪静态未生效」表现:Nginx 没把请求转发给 index.php 入口,而是直接去文件系统找 /xxx 这个路径——当然找不到,就返回 404。
- 常见于 Laravel、Lumen、ThinkPHP 等依赖 PATH_INFO 或重写的框架
- Windows 下尤其容易漏掉
if (!-e $request_filename)或try_files配置 - phpstudy、laragon 等集成环境默认不开启重写,需手动补全
nginx.conf 中必须改的两个关键位置
打开 nginx/conf/nginx.conf,重点检查并修正以下两处:
-
root 路径要和你的项目实际目录一致,比如项目在
D:/www/laravel,则location / { root D:/www/laravel; }——不能写成html或留空 -
PHP 处理块中的
SCRIPT_FILENAME必须用$document_root$fastcgi_script_name,而不是硬编码的/scripts$fastcgi_script_name或错误拼接的$document_root/$fastcgi_script_name(少斜杠或多数斜杠都可能失败) - 确保
fastcgi_pass 127.0.0.1:9000和你启动的 php-cgi 端口一致(常见端口:9000、9001)
正确示例:
立即学习“PHP免费学习笔记(深入)”;
location ~ \.php$ {
root D:/www/laravel;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
重写规则必须加,且 Windows 下推荐用 try_files
if (!-e $request_filename) { ... } 在 Windows 上偶尔失效,更稳定的做法是用 try_files 替代。
- 在
location /块内添加:try_files $uri $uri/ /index.php?$query_string; - 如果框架依赖 PATH_INFO(如 ThinkPHP 5),则改用:
try_files $uri $uri/ /index.php$uri?$args; - 注意:不要同时存在
if和try_files,Nginx 官方明确建议避免if用于重写逻辑
php.ini 里容易被忽略的开关
即使 Nginx 配对了,PHP 层若关闭 pathinfo 支持,$_SERVER['PATH_INFO'] 仍为空,导致路由解析失败。
- 打开
php.ini,确认cgi.fix_pathinfo=1(不是 0,也不是被注释掉) - 某些旧版 PHP(如 5.2~5.6)还要求
enable_dl = On才能加载扩展,虽不直接影响 404,但会连锁引发其他问题 - 修改后必须重启 php-cgi 进程(关掉命令行窗口再重跑
php-cgi.exe -b 127.0.0.1:9000)
最常踩的坑是:改了 nginx.conf 却忘了 reload(nginx -s reload),或改了 php.ini 却没重启 php-cgi —— 这两个动作缺一不可。



















