Route::domain() 不生效的根本原因是请求未进入 ThinkPHP,需检查 hosts 文件解析、Web 服务器 server_name 配置、fastcgi_param HTTP_HOST 传递、try_files 写法及路由注册顺序。

Route::domain() 不生效,本地打不开子域名
根本不是框架 bug,是请求压根没进到 ThinkPHP。你的电脑没把 admin.test 解析到 127.0.0.1,Nginx 或 Apache 也没配 server_name admin.test。Windows 改 C:\Windows\System32\drivers\etc\hosts,macOS/Linux 改 /etc/hosts,加一行:127.0.0.1 admin.test。Nginx 配置里必须有 server_name admin.test;,且 root 指向项目 public 目录。别用 php -S 跑——它不传 Host 头,Route::domain() 永远不会触发。
Nginx 下 domain 绑定后 500 或跳默认路由
错误日志里出现 Undefined index: HTTP_HOST,说明 $_SERVER['HTTP_HOST'] 没传进来。ThinkPHP 的域名路由全靠这个变量。检查 Nginx 的 fastcgi_params 或站点配置,必须包含这一行:fastcgi_param HTTP_HOST $http_host;。阿里云轻量、腾讯云 CVM 的默认模板常删掉这行,手动补上。如果用了 try_files,别写成 try_files $uri /index.php?_url=$uri 这种会覆盖原始 Host 头的写法;安全写法是 try_files $uri /index.php?$query_string。
多个 domain 绑定共存但只生效一个
php think route:list 默认只显示主域名下的路由,其他 Route::domain() 定义的子域规则不会列出来——不代表没注册成功。更关键的是:如果两个绑定都定义了相同路径(比如都写了 admin/),ThinkPHP 按注册顺序匹配,后注册的会被前一个吞掉,它不校验当前请求是否真命中该 domain。调试时直接 var_dump(Route::getRules()),看返回数组里 domain 键下有没有对应子数组,确认规则是否真实加载。
TP5 域名跳转后控制器不存在
常见于根目录放了中转 index.php(比如 require __DIR__ . '/home/public/index.php';),但没同步修正 url() 函数逻辑。原生 url() 生成的地址不含入口文件路径,导致生成的链接如 /index.php/admin/index 实际访问时被服务器当成根目录下的 admin 控制器,自然报错。必须修改 thinkphp/helper.php 中的 url() 函数,在调用 Url::build() 前手动拼上前缀:$url = '/home/public/index.php/index/' . $url;。注意路径要和你实际的入口文件位置一致,且不能漏掉 /index/ 这一段。
立即学习“PHP免费学习笔记(深入)”;
跨域中间件和域名绑定本身不冲突,但如果你在中间件里用header() 强行跳转,或者在 url() 函数里硬编码了旧域名,就会干扰 domain 路由的正常匹配流程。这类问题往往藏得深,得从请求头、服务器配置、框架路由规则三层一起对齐。



















