ThinkPHP5域名绑定模块访问出错的根本原因是域名、入口文件与pathinfo三者未对齐:hosts未配置导致DNS失败、Nginx server_name不匹配、fastcgi_param缺失HTTP_HOST或PATH_INFO、admin.php未被正确执行,致使Route::domain()不触发、request()->host()返回localhost、URL生成错误。

ThinkPHP5 域名绑定后模块访问路径出错,根本不是路由写错了,而是域名、入口文件、pathinfo 三者没对齐——尤其当用 admin.php 作后台入口又绑了子域名时,request()->host() 可能取到 localhost,Route::domain() 根本不触发,PATH_INFO 还为空,三重失效叠加。
Route::domain() 不生效:先确认请求真进到了框架里
本地或测试环境里,Route::domain('admin.example.com', function () { ... }) 完全没反应,连调试日志都不打,大概率是请求压根没走到 ThinkPHP。常见原因:
- hosts 文件没加
127.0.0.1 admin.example.com,浏览器直接 DNS 失败 - Nginx 配置里
server_name写的是example.com,不是admin.example.com - 用了
php -S内置服务器——它不解析 Host 头,Route::domain()在里面永远为假 - Nginx fastcgi_params 缺少
fastcgi_param HTTP_HOST $http_host;,导致$_SERVER['HTTP_HOST']为空,框架无法提取域名
访问 admin.php 提示“模块不存在”:入口文件和 pathinfo 没配对
你绑了 admin.example.com,Nginx 也配了 server_name admin.example.com,但访问 http://admin.example.com/manager/login 还是报 module not exists: index,问题出在 pathinfo 解析失败:
- Nginx location 块没启用 pathinfo,
$_SERVER['PATH_INFO']是空的,框架只能拿到/index.php,后面路径全丢了 - fastcgi_param 中漏了
fastcgi_param PATH_INFO $fastcgi_path_info;或等效配置(如用try_files $uri $uri/ /admin.php?$query_string;时未保留原始路径) - 入口文件是
admin.php,但 Nginx 的fastcgi_index还设成index.php,导致 PHP 实际执行的是 index.php 而非 admin.php - Apache 用户要确认
mod_rewrite开启,且.htaccess里没用RewriteCond %{HTTP_HOST}干扰 Host 透传
request()->host() 返回 localhost 或 IP:别信 $_SERVER['HTTP_HOST'] 手动读取
你在控制器里打印 request()->host() 得到 localhost:8080 或 172.18.0.3:9000,说明 Web 服务器没把真实 Host 头传进来,或者你在 CLI/队列里调用了它(那本来就不该有 Host):
立即学习“PHP免费学习笔记(深入)”;
- 反向代理场景下,Nginx 必须透传
X-Forwarded-Host并在 PHP 中启用trust_proxy配置,否则request()->host()只读$_SERVER['HTTP_HOST'],而这个值来自代理内网地址 - 阿里云/腾讯云轻量服务器的默认 Nginx 模板常删掉
fastcgi_param HTTP_HOST $http_host;,补上才能让框架拿到真实域名 - 绝对不要在生产环境手动写
$_SERVER['HTTP_HOST']拼链接——它可被伪造,做租户隔离或资源 URL 生成时会出安全问题
url() 生成链接带错域名:检查 url_domain_deploy 和入口一致性
url('manager/login') 生成的链接是 https://example.com/manager/login,而不是你期望的 https://admin.example.com/manager/login,说明域名绑定没参与 URL 生成流程:
-
'url_domain_deploy' => true没在config/app.php里开启,该配置是 URL 生成走 domain 绑定的前提 - 虽然绑定了
admin.example.com,但当前请求实际是通过example.com进来的(比如 hosts 指向错误或 DNS 缓存),框架按实际请求域名生成,不是按你“想绑”的域名 - 入口文件不统一:主站走
index.php,后台走admin.php,但两个入口的配置加载逻辑不同,url_domain_deploy可能在 admin.php 环境里没生效
最易被忽略的一点:多域名绑定共存时,php think route:list 默认只显示主域名下的路由,admin.example.com 的路由不会列出来——不能靠这个命令判断是否注册成功,得用 var_dump(Route::getRules()) 看完整规则数组里有没有 domain 键。



















