多站点共用IP时,ThinkPHP6在Nginx下必须逐级隔离:每个域名配独立server块并设root指向对应public目录;删除宝塔默认TP5规则,改用多应用专用rewrite规则;运行目录必须选/public,开启url_domain_deploy并用Route::domain()分组路由。

多个站点共用一个IP时,ThinkPHP6在Nginx下不能靠一套伪静态规则“通用所有域名”,必须从服务器层到框架层逐级隔离——否则请求会错进其他站点的index.php,轻则404,重则路由混用、参数污染。
每个域名配独立server块
Nginx不支持运行时按域名动态加载规则,所有分流逻辑必须写死在配置中:
- www.example.com、admin.example.com、api.example.com,哪怕共用同一IP和端口,也必须各自定义一个
server块 - 每个
server块内root必须明确指向对应项目的public/目录,例如:root /var/www/admin/public; - HTTPS站点需单独写
server { listen 443 ssl; },里面的try_files或rewrite规则要完全一致,不可复用HTTP块 -
server_name必须精确匹配,避免用泛域名(如*.example.com)导致请求被错误捕获
伪静态规则要适配多应用结构
TP6多应用依赖URL首段识别应用名(如/admin/login中的admin),宝塔默认的单应用规则会直接失效:
- 删除宝塔面板里已有的“ThinkPHP”伪静态模板(它是为TP5设计的)
- 在每个
server块的location /中粘贴专用多应用规则:
rewrite ^/([a-z0-9A-Z_\-]+)/(.*)$ /index.php?s=$1/$2 last;
rewrite ^/(.*)$ /index.php?s=$1 last;
}
- 第一行捕获带应用前缀的路径(如
/admin/user→s=admin/user) - 第二行兜底处理根路径、静态资源等,确保不漏转发
-
last是关键:它让重写后重新进入location匹配流程,保障PHP-FPM能正确加载
运行目录和PHP配置必须同步对齐
规则再准,这两项设错就全白搭:
立即学习“PHP免费学习笔记(深入)”;
- 宝塔 → 网站 → 设置 → 网站目录 → 运行目录 → 必须从下拉菜单选择
/public(不是手动填,也不是留空) - 点完立即点击右上角「重载Nginx」——只点「保存」无效,旧进程仍在跑
- PHP禁用函数中不能勾选
putenv和ini_set(TP6启动时靠它们动态设置PATH_INFO) - 检查PHP处理块是否含
fastcgi_param PATH_INFO $fastcgi_path_info;,且前面有fastcgi_split_path_info ^(.+\.php)(/.+)$;
框架内开启域名路由分组
服务器层分流只是第一步,框架内不隔离,请求仍可能被其他站点路由捕获:
- 在
config/app.php中开启url_domain_deploy,设为true - 路由定义改用
Route::domain()分组,例如:
Route::get('user/list', 'admin.User/index');
});
- 不要用
$_SERVER['HTTP_HOST']手动判断——TP6的Route::domain()在路由解析早期就截断非匹配域名请求,更安全也更高效



















