根本原因是路由定义顺序、作用域隔离和缓存机制未对齐:静态路径被通配规则优先匹配;route::domain()未用闭包重定义专属路由导致失效;全局路由缓存未按子域隔离引发共用与性能下降。

ThinkPHP 配置二级域名后出现路由冲突,根本原因不是域名本身出错,而是路由定义顺序、作用域隔离和缓存机制三者没对齐。静态路径被通配规则吃掉、不同子域共用同一套路由、Route::domain() 里漏写具体规则——这些才是真实痛点。
路由定义顺序必须“从具体到泛化”
ThinkPHP 路由不按“匹配精度”排序,只按代码书写顺序逐条比对,先命中就停止。二级域名下尤其容易踩坑:比如 Route::get('user/:id', ...) 写在 Route::get('user/profile', ...) 前面,访问 /user/profile 就会把 profile 当作 :id 值传入,控制器逻辑直接错乱。
- 所有不含变量的完整路径(如
admin/login、api/status)必须放在最前面 - 含单个变量的规则(如
user/:id、post/:slug)紧随其后,但不能覆盖已有静态子路径 -
user/:id/edit必须排在user/:id后面,否则/user/123/edit中的:id会匹配成"123/edit" -
Route::miss()和通配符user/*一定放在最后,它们是兜底项,不是优先项
二级域名路由必须显式闭包定义
Route::domain() 不是给某条规则加个标签,而是一个独立作用域。你在全局写的 Route::rule('user/:id', 'User/read'),对 api.example.com 完全无效——它只属于主域名上下文。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 每个二级域名都要用
Route::domain('api.example.com', function ($r) { ... })包裹全部该域专属路由 - 闭包内必须调用
$r->get()、$r->post()或$r->resource(),不能继续用Route::静态调用 - 泛域名
Route::domain('*')可作兜底,但需显式声明所有需要支持的动词方法,且优先级低于已命名的子域 - 若用 Nginx 或 Apache,确保反向代理透传
Host头,否则$_SERVER['HTTP_HOST']可能是localhost,导致域名匹配失败
变量约束与缓存隔离双管齐下
二级域名常伴随差异化业务,比如 admin.example.com 要求数字 ID,shop.example.com 允许字母短链。全局 __pattern__ 会误伤这类需求;而默认路由缓存不区分域名,又会让多子域共用一份缓存,加载时反复筛选、性能下降。
- 禁用宽泛的全局
__pattern__,改用局部->pattern(['id' => '\d+'])或内联正则user/:id([0-9]+) - 启用多应用模式后,为每个子域对应的应用单独生成路由缓存:
php think route:cache --app=admin、php think route:cache --app=shop - 配置缓存也需分域,例如在
config/app.php中将缓存前缀设为'cache_prefix' => $_SERVER['HTTP_HOST'] . ':' - 关闭伪静态后缀(
'url_html_suffix' => ''),避免中文或 Base64 字符被截断
URL 生成要带域名才真正闭环
路由匹配成功 ≠ 前端能正确请求。默认 url('api.User/index') 生成的是相对路径或当前域名链接,跨子域调用时易 404 或跨域失败。
- 开启域名部署:
'url_domain_deploy' => true(写在config/route.php) - 确保
Route::domain()闭包中注册的路由,在生成 URL 时能关联到对应域名 - 必要时手动指定域名:
url('api.User/index', [], true, 'https://api.example.com') - 检查
url()是否被中间件或模板函数二次处理,导致协议/域名被抹除
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










