Nginx子目录部署ThinkPHP需配置alias或rewrite规则适配public路径,修复404、PATH_INFO错乱及open_basedir限制,并验证权限、日志与调试模式。

如果您已将ThinkPHP项目部署在Nginx服务器的子目录(如 /myapp)下,但访问 domain.com/myapp 时出现404、入口文件不触发或PATH_INFO错乱等问题,则很可能是Nginx未正确适配子目录路径结构与ThinkPHP的路由机制。以下是多种可行的子目录部署配置方案:
一、使用 location 前缀匹配 + alias 指向 public 目录
该方法通过 alias 指令将URL路径精确映射到物理目录,避免 root 的路径拼接歧义,是子目录部署最稳妥的方式。需确保 Nginx 用户对 public/ 及其上级目录具备执行(x)权限以 traversing。
1、确认您的ThinkPHP项目结构中,public 目录位于子目录内部,例如:/var/www/html/myapp/public/
2、编辑站点配置文件(如 /etc/nginx/conf.d/myapp.conf),在 server 块内添加如下 location 块:
立即学习“PHP免费学习笔记(深入)”;
3、location /myapp/ { alias /var/www/html/myapp/public/; }
4、在该 location 块内追加 PHP 处理逻辑与伪静态规则:
5、location ~ ^/myapp/(.+\.php)$ { alias /var/www/html/myapp/public/$1; fastcgi_pass unix:/run/php/php8.1-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; }
6、再添加一条用于处理非PHP资源及路由转发的规则:
7、location /myapp/ { alias /var/www/html/myapp/public/; try_files $uri $uri/ /myapp/index.php?$query_string; }
二、使用 rewrite + root 配合 PATH_INFO 兼容模式
此方案适用于无法使用 alias 或需复用现有 root 配置的场景,通过重写 URL 并显式传递 s 参数模拟 PATH_INFO,绕过 Nginx 对 fastcgi_split_path_info 的依赖。
1、确保 server 块的 root 指向项目根目录上级,例如:root /var/www/html;
2、添加针对子目录的 rewrite 规则块:
3、location /myapp/ { try_files $uri $uri/ @myapp; }
4、定义命名 location 处理路由回退:
5、location @myapp { rewrite ^/myapp/(.*)$ /myapp/public/index.php?s=/$1 last; }
6、单独配置 PHP 处理,确保 SCRIPT_FILENAME 正确指向 public 下的 index.php:
7、location ~ ^/myapp/public/.*\.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php8.1-fpm.sock; }
三、使用嵌套 location + internal 重定向规避路径泄露
该方法通过内部重定向将所有子目录请求统一交由 public/index.php 处理,同时防止敏感目录(如 application/、config/)被直接访问,增强安全性。
1、设置 server 级 root 为项目根目录,例如:root /var/www/html/myapp;
2、禁止直接访问非 public 路径下的敏感目录:
3、location ~ ^/(application|config|route|runtime|vendor|thinkphp) { deny all; }
4、为子目录路径启用内部重定向逻辑:
5、location /myapp/ { try_files $uri $uri/ /myapp/public/index.php?$query_string; }
6、配置 public 目录下的 PHP 执行入口,注意使用 alias 显式定位:
7、location /myapp/public/ { alias /var/www/html/myapp/public/; location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix:/run/php/php8.1-fpm.sock; } }
四、修复常见子目录404与open_basedir限制
当子目录部署后出现 500 错误或 “open_basedir restriction in effect” 提示,本质是 PHP 的安全路径限制未覆盖子目录下的真实物理路径,导致 require() 失败。
1、检查当前 open_basedir 设置,执行:php -i | grep open_basedir
2、定位 fastcgi_params 或站点 conf 中的 fastcgi_param PHP_ADMIN_VALUE 行
3、将子目录完整路径加入 open_basedir 白名单,例如:
4、fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/html/myapp/:/var/www/html/myapp/public/:/tmp/:/proc/";
5、若使用 Docker 或共享主机环境,也可临时注释该行以验证是否为此原因所致
6、修改后必须重启 php-fpm:sudo systemctl restart php8.1-fpm
五、验证子目录部署是否生效的关键检查项
完成任一方案配置后,需逐项验证基础运行条件是否满足,避免因低级配置疏漏导致调试失败。
1、确认 Nginx 工作进程用户(如 www-data)对 /var/www/html/myapp/public/ 具有读取与执行权限
2、执行:ls -ld /var/www/html/myapp /var/www/html/myapp/public,确保每级父目录均有 x 权限
3、检查 public/index.php 是否可被 Nginx 直接访问(如 curl http://localhost/myapp/public/index.php),排除文件权限或SELinux拦截
4、查看 Nginx error log:tail -f /var/log/nginx/error.log,实时捕获 rewrite 或 fastcgi 错误
5、确认 ThinkPHP 的 APP_DEBUG 已开启且 .env 中未强制覆盖 APP_ENV=production



















