ThinkPHP5子域名绑定伪静态必须同时满足:开启url_domain_deploy顶级配置、Nginx透传HTTP_HOST与PATH_INFO、route.php中用闭包定义Route::domain(),缺一不可。

ThinkPHP5 伪静态 + 子域名绑定,必须同时满足三件事:框架开启域名路由、Web 服务器正确透传 Host 和 PATH_INFO、路由定义写在 route.php 且格式合法。缺一不可,否则访问子域名会直接 fallback 到默认模块,连错误都不报。
必须开启 url_domain_deploy 配置
TP5 默认完全忽略 Host 头,不打开这个开关,Route::domain() 就是摆设——不会报错,也不会匹配,静默失效。
- 在
application/config.php(或config/app.php)顶层数组中添加:'url_domain_deploy' => true - 不要写成
'app.url_domain_deploy'或嵌套在route键下,它必须是顶级配置项 -
APP_SUB_DOMAIN_DEPLOY是 TP3 遗留字段,TP5.1+ 已废弃,设了也无效
Route::domain() 必须写在 route.php 里,且第二参数不能是字符串
常见翻车点:把 Route::domain('admin.example.com', 'admin') 这种写法当真,结果 PHP 直接抛出 Invalid route rule 异常。
- 正确写法只接受闭包或数组:
Route::domain('admin.example.com', function () { Route::get('/', 'index/index'); }) - 如果用数组方式,必须确保
require 'route/admin.php'返回的是标准路由定义数组(如return ['/' => 'index/index']) - 别把规则塞进
config/route.php或中间件里,TP5 只扫描route.php(通常是application/route.php)
Nginx 必须透传原始 HTTP_HOST 和 PATH_INFO
即使 PHP 层配置全对,Nginx 拦了一道,请求根本到不了 TP5 入口。
立即学习“PHP免费学习笔记(深入)”;
-
fastcgi_param HTTP_HOST $host;—— 必须用$host,不是$server_name;否则$_SERVER['HTTP_HOST']拿不到真实子域名 -
fastcgi_param PATH_INFO $fastcgi_path_info;—— 缺了这句,TP5 启动时会中断并报URL pathinfo not supported - 伪静态规则要指向
/public/index.php,不是/index.php;宝塔用户务必在「网站设置 → 运行目录」选/public
本地测试必须改 hosts,且子域名要写全
浏览器访问 http://admin.example.com 时,DNS 解析必须返回 127.0.0.1,否则 Nginx 根本收不到请求,更别说 TP5。
- Windows:编辑
C:\Windows\System32\drivers\etc\hosts,加两行:127.0.0.1 example.com和127.0.0.1 admin.example.com - macOS/Linux:改
/etc/hosts,同样加两行,不能只写*.example.com(hosts 不支持通配符) - 别用
localhost:8080测试子域名逻辑,request()->subDomain()会返回空,因为没点分隔
最容易被忽略的其实是 Nginx 的 HTTP_HOST 传递和 route.php 的闭包包裹——这两处一错,其他全对也没用。尤其上线前,一定要用 var_dump($_SERVER['HTTP_HOST']) 在入口文件里确认拿到的是 admin.example.com,而不是 example.com 或空值。



















