本地域名绑定失败90%是hosts未生效,须先配置hosts文件(如127.0.0.1 admin.test)、刷新DNS缓存并ping验证,再确保Nginx/Apache指向public目录、透传HTTP_HOST,且Route::domain()仅在route/app.php中注册有效,禁用php -S。

本地域名绑定失败,90% 是 hosts 没生效
ThinkPHP 的 Route::domain() 在本地根本跑不起来,不是路由写错了,而是浏览器压根没把 admin.test 解析成 127.0.0.1。所有后续配置都建立在这个前提上。
必须做三件事:
- Windows:用管理员权限打开
C:\Windows\System32\drivers\etc\hosts,追加一行127.0.0.1 admin.test(不能有空格、不能带http://、不能写成localhost) - macOS/Linux:执行
sudo nano /etc/hosts,同样加127.0.0.1 admin.test - 改完立刻刷新 DNS 缓存:
ipconfig /flushdns(Win)或sudo dscacheutil -flushcache(macOS)
验证是否成功:终端运行 ping admin.test,看到回复来自 127.0.0.1 才算过关。否则别往下调 Nginx 或框架配置。
Nginx/Apache 必须把请求真正交给 public/index.php
即使 admin.test 能 ping 通,Web 服务器没配对,请求也进不了 ThinkPHP。常见错误是 root 指向错目录,或重写规则丢掉了 HTTP_HOST。
立即学习“PHP免费学习笔记(深入)”;
Nginx 关键点:
-
root必须指向项目public/目录,不是项目根目录 -
location块里必须用try_files $uri $uri/ /index.php?$query_string;,不能简化为/index.php?_url=(会丢HTTP_HOST,导致Route::domain()匹配失败) - 改完执行
sudo nginx -s reload
Apache 关键点:
- 确认启用了
mod_rewrite(a2enmod rewrite或检查00-base.conf) -
DocumentRoot指向public/ -
<directory></directory>块中必须同时有AllowOverride All和Require all granted
Route::domain() 只在 route/app.php 中注册才有效
ThinkPHP5 的域名路由只认 route/app.php 这一个入口。写在 config/route.php、控制器里、或者多应用模式下的其他路由文件,全被忽略。
写法必须严格:
-
Route::domain('admin.test', [])第二个参数只能是数组或闭包,不能是字符串路径(比如'admin/index/index'会报Invalid route rule) - 闭包内必须重新定义该域名下全部路由,不能依赖外部
Route::rule();例如Route::get('user', 'admin.User/read')要写在闭包里 - 本地开发时
HTTP_HOST可能带端口(如admin.test:8080),绑定要写完整,或加判断:if (APP_DEBUG) Route::domain('localhost:8080', []);
php -S 内置服务器根本不支持域名绑定
这是最硬的限制:执行 php -S 127.0.0.1:8000 public/router.php 时,PHP 内置服务器压根不解析 Host 请求头,$_SERVER['HTTP_HOST'] 为空或不可靠,Route::domain() 必然失效。
想本地测试域名路由,必须用真实 Web 服务器(Nginx/Apache)——哪怕只是开发机上的最小化配置。别在 php -S 上浪费时间调 app.domain_bind 或重写规则。
真正容易被忽略的是:你改了 hosts、写了 Route::domain()、甚至 reload 了 Nginx,但只要没关掉正在跑的 php -S 进程,浏览器访问的还是那个不认 Host 的服务。



















