ThinkPHP6中域名路由必须用Route::domain()显式声明且仅在route/app.php生效;第二参数须为闭包或数组,不可为字符串;Web服务器需将请求统一转发至public/index.php,否则路由不触发。

独立域名在 ThinkPHP6 里不能靠 config 配置项或 bind 绑定实现,必须用 Route::domain() 显式声明,且 Web 服务器要把该域名请求全部转发到 public/index.php —— 否则路由压根不会触发。
Route::domain() 是唯一生效的域名路由方式
很多人在 config/route.php 或 config/app.php 里写 'bind' => ['api' => 'api'],以为能绑定 api.example.com,结果完全没用。ThinkPHP6 的域名路由是纯路由层能力,只认 Route::domain()。
-
Route::domain('api.example.com', function () { Route::get('/user', 'Api/User/index'); });这样才生效 - 多个域名可传数组:
Route::domain(['api.example.com', 'v1.example.com'], function () { ... }); - 泛域名需显式捕获:
Route::domain('{sub}.example.com', function () { ... });,再用$sub参数做逻辑分支 - 不能在
domain()回调里再嵌套Route::domain(),TP 6.1+ 会直接报错Domain route not support nested
Nginx/Apache 必须统一指向 public/index.php
ThinkPHP 不监听端口或 host,它依赖 Web 服务器把所有域名请求都打到同一个入口文件,再由框架读取 $_SERVER['HTTP_HOST'] 匹配路由。一旦你给 api.example.com 单独配了个 root 指向别的目录,请求根本进不了 TP,直接 404 或返回静态文件。
- Nginx 的
server_name api.example.com;块中,root必须和主站一致,例如/var/www/project/public - Apache 的
VirtualHost中,DocumentRoot也必须指向同一public目录,并启用mod_rewrite - 本地开发别用
php -S,它不支持多 host;改用 Nginx、Docker 或 DnsProxy 类工具临时映射 hosts
跨域、HTTPS、Cookie 等不是路由层的事
Route::domain() 只管路由匹配,不自动处理跨域头、SSL 重定向或 Cookie 域名作用域。这些得单独配:
立即学习“PHP免费学习笔记(深入)”;
- 跨域必须启用
think\middleware\Cors中间件,不能只靠路由;origin设为*时,withCredentials必须关掉,否则浏览器拒绝 - HTTPS 下若要带 Cookie,
setcookie()或 Session 配置里得显式设domain=.example.com(注意开头的点) - 如果用了 Swoole/RoadRunner,注意进程复用会导致
APP_PATH或中间件状态污染,每次请求都得重置
最容易被忽略的是:Web 服务器配置错误导致请求压根没进框架,这时候查 route.php 再仔细也没用。先确认 curl -I http://api.example.com/ 返回的是否是 TP 的响应头(比如 X-Powered-By: ThinkPHP),再往下排查路由定义。


















