PHP 8.2 + Nginx 配置二级路径(如 /admin/)必须同时处理静态资源路径剥离、PHP 脚本准确定位、FPM 权限与 socket 匹配三件事:用 alias(结尾带斜杠)替代 root;SCRIPT_FILENAME 必须用 $realpath_root$fastcgi_script_name;fastcgi_pass 严格匹配 PHP-FPM 的 Unix socket 路径及权限。

PHP 8.2 + Nginx 要跑在二级路径(比如 /admin/),不能只改 root 或硬套默认配置,必须同时处理三件事:静态资源路径剥离、PHP 脚本定位、FPM 权限与 socket 匹配。漏掉任一环,轻则 404/403,重则 502。
用 alias 挂载 PHP 子应用,不是 root
想把 /admin/ 映射到 /var/www/admin/?别用 root,它会把 /admin/ 拼进去,导致实际找的是 /var/www/admin/admin/index.php —— 多了一层,必 404。
-
location必须以斜杠结尾:location /admin/ { ... } -
alias值也必须以斜杠结尾:alias /var/www/admin/; - PHP 文件访问路径(如
/admin/index.php)会被完整剥离前缀,Nginx 直接读取/var/www/admin/index.php - Vue/React 等打包产物需设
publicPath: "/admin/",否则js/app.js会请求根目录下的路径
fastcgi_param SCRIPT_FILENAME 必须用 $realpath_root
PHP 8.2 默认开启 opcache.enable 和符号链接检查,旧写法 SCRIPT_FILENAME $request_filename 在 alias 下会失效,因为 $request_filename 不解析真实路径,容易触发 404 或 500。
- 正确写法:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - 必须配合
alias使用;root下也可用,但非必须 - 确保
nginx.conf里已加载fastcgi_params,且该文件中未覆盖此参数 - 若仍报 “No input file specified”,检查
$realpath_root是否为空——常见于alias路径末尾漏斜杠或路径不存在
fastcgi_pass 指向 PHP 8.2 的 Unix socket,权限要对齐
PHP 8.2 几乎都用 Unix socket(如 /run/php/php8.2-fpm.sock),而不是 127.0.0.1:9000。配错就 502,日志里只有 connect() to unix:/run/php/php8.2-fpm.sock failed。
立即学习“PHP免费学习笔记(深入)”;
- 先确认 socket 存在:
ls -l /run/php/php8.2-fpm.sock - 看 FPM pool 配置(如
/etc/php/8.2/fpm/pool.d/www.conf)中的listen.owner和listen.group,通常为www-data - Nginx 的
user指令也得是www-data(或对应用户),否则无权访问 socket - 检查
listen.mode = 0660,太松(0666)不安全,太紧(0600)Nginx 进程连不上
二级路径下 PHP 脚本的 $_SERVER['SCRIPT_NAME'] 和路由问题
即使 Nginx 配置全对,PHP 应用本身也可能“不知道”自己跑在二级路径里。比如 Laravel 的 url() 生成绝对路径时,默认还是从 / 开始,导致 CSS/JS 404 或跳转回根目录。
- Laravel:在
.env中设APP_URL=https://example.com/admin,并确保public/.htaccess(Apache)或 Nginx 的try_files规则不干扰 - 原生 PHP:用
$_SERVER['SCRIPT_NAME']判断当前路径前缀,或手动定义BASE_PATH = '/admin' - 不要依赖
$_SERVER['REQUEST_URI']去截断前缀——Nginx 已剥离,它拿到的是/index.php,不是/admin/index.php
最常被忽略的一点:alias 后的物理路径必须真实存在、可读、父目录有执行(x)权限,且 Nginx 日志里 open() 调用的路径要和你预期完全一致——建议临时开 error_log /var/log/nginx/error.log debug; 看一行真实的文件打开路径。



















