Nginx虚拟目录PHP返回404主因是请求未进入PHP层,属“真404”:需确认root指向public/目录、location /含try_files $uri $uri/ /index.php?$query_string、location ~ \.php$完整配置fastcgi_pass及SCRIPT_FILENAME参数,并彻底重启服务。

Nginx虚拟目录下PHP解析返回404,绝大多数情况不是PHP代码或路由出错,而是请求压根没进PHP层——Nginx在文件查找阶段就判定“不存在”,直接返回404,根本没转发给PHP-FPM。
关键要分清:这是真404(Nginx未找到任何匹配资源,连index.php都没执行),不是框架返回的“伪404”(PHP已运行,但路由没匹配)。
确认是不是真404
用最简单方式验证:
在 public/index.php 开头加一行
<?php die('PHP executed');然后访问任意子路径,比如 /test 或 /user/login。
- 如果看到
PHP executed→ 说明重写生效,问题在PHP层(如框架路由、PATH_INFO配置等); - 如果仍是 404 页面或空白 → 确认是真404,问题100%出在Nginx配置。
再补一个检查:
立即学习“PHP免费学习笔记(深入)”;
curl -I http://localhost
- 若响应头里没有
X-Powered-By: PHP,基本可断定PHP根本没参与处理。
Nginx root 必须指向 public/ 目录
ThinkPHP、Laravel、Symfony 等现代框架要求 Web 根目录是 public/,不是项目根目录。
错误示例:
root /var/www/myapp; # ❌ 找 /var/www/myapp/index.php → 不存在
正确写法:
root /var/www/myapp/public; # ✅ 末尾不加斜杠
Windows 下用 phpEnv 时同理:
- Apache:
DocumentRoot "D:/phpEnv/www/myproject/public" - Nginx:vhost 中
root "D:/phpEnv/www/myproject/public";
大小写敏感(Linux/macOS):Public、PUBLIC、public 不等价,必须完全一致。
location / 块必须含 try_files 规则
所有非静态资源请求(如 /login、/api/v1/users)必须被重写到 index.php,否则Nginx按字面路径找文件,自然404。
标准写法(推荐):
location / {
index index.php;
try_files $uri $uri/ /index.php?$query_string;
}-
$uri:先查真实文件(如.js,.css) -
$uri/:再查目录(如/admin/) -
/index.php?$query_string:都不命中,全部交由入口处理
⚠️ 注意:try_files 必须写在 location / 块内,不能漏,也不能放在其他 location 里。
location ~ .php$ 块不能缺失且参数要完整
这个块负责把 .php 请求交给 PHP-FPM。缺了它,.php 文件会当普通文件下载或报404。
必须包含以下几项:
-
fastcgi_pass:指向正在运行的 PHP-FPM 实例,例如fastcgi_pass unix:/run/php/php8.0-fpm.sock;或fastcgi_pass 127.0.0.1:9000; -
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
(这是最关键的参数,决定PHP-FPM执行哪个文件) -
include fastcgi_params; fastcgi_index index.php;
如果框架依赖 PATH_INFO(如 ThinkPHP 3.2),还需加:
fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info;
改完配置后必须彻底重启 Nginx
phpEnv 面板点“重启服务”≠重载配置,尤其修改了 vhost 或 nginx.conf 后:
- 正确操作:先「停止」Nginx,再「启动」;
- 或命令行进入
phpEnv/nginx/目录,执行:nginx -s stop && nginx
(不是
nginx -s reload,某些旧版 phpEnv 不支持热重载)
同时确认 PHP-FPM 服务已运行:
systemctl status php8.0-fpm # Linux # 或 Windows 下看 phpEnv 面板中 PHP-FPM 是否绿色运行中



















