ThinkPHP 6 嵌套路由必须用 group() 多层嵌套,不支持单 group 多级前缀;控制器命名空间需手动完整指定,不自动继承;资源路由在分组中也要显式写全类名;调试以 php think route:list 输出为准。

ThinkPHP 6 的嵌套路由分组必须用 group() 嵌套调用
ThinkPHP 6 不支持在单个 Route::group() 中直接写多级路径前缀(比如 'admin/user')来模拟嵌套;真要实现「路由分组套分组」,必须显式调用多次 group(),每次包裹下一层闭包。这是最常被误写的点——很多人以为写成 Route::group('admin.user', [...]) 就能嵌套,其实那只是字符串拼接,不产生层级作用域。
正确做法是:
use thinkacadeRoute;
Route::group('admin', function () {
Route::group('user', function () {
Route::get('list', 'Admin\User::list');
Route::post('add', 'Admin\User::add');
});
Route::group('order', function () {
Route::get('index', 'Admin\Order::index');
});
})->middleware('check_auth');
这样生成的完整路由是 /admin/user/list、/admin/order/index,且中间件 check_auth 会作用于整个 admin 分组,而子分组可额外追加中间件。
嵌套时控制器命名空间不会自动继承,得手动补全
TP6 的路由分组**不改变闭包内控制器类的解析规则**:它只拼接 URL 路径前缀,不自动推导命名空间。哪怕你在 admin 分组里再套 user 分组,'User::list' 依然会被解析为当前应用默认命名空间下的 User 类(通常是 appcontrollerUser),而不是你想要的 appcontrollerdminUser。
立即学习“PHP免费学习笔记(深入)”;
- 错误写法:
Route::get('list', 'User::list')→ 找不到appcontrollerUser - 正确写法:
Route::get('list', 'Admin\User::list')或Admin.User/list(方法名风格) - 如果用了多模块,还要带上模块名,比如
'admin/Admin.User/list'
别依赖“路径像目录就自动映射命名空间”,TP6 没这机制。
嵌套路由和资源路由一起用容易漏掉动作绑定
资源路由 Route::resource() 在嵌套分组里不会自动适配父级前缀,它的内部路径是相对的,但控制器类仍需手动指定完整命名空间。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
比如想注册 /admin/article 下的资源路由:
Route::group('admin', function () {
Route::resource('article', 'Admin\Article')->name('admin.article');
});
这会正确生成 /admin/article、/admin/article/create 等路径,但如果你漏写了 Admin\Article,它就会去加载 appcontrollerArticle,报错 Class appcontrollerArticle does not exist。
另外注意:->name() 是给路由起别名,不是设置命名空间,别混淆。
调试嵌套路由时,php think route:list 是唯一可信依据
嵌套多了容易自己都搞不清最终 URL 和控制器对应关系。别靠猜,执行命令:
php think route:list
它会输出所有注册后的完整路由表,含 Method、URI、Controller@Action、Name 四列。重点看 URI 列是否符合预期(比如是不是多出了双斜杠 //),以及 Controller@Action 是否指向你写的类。
常见坑:
- 分组前缀末尾带斜杠(如
Route::group('admin/', ...))→ 导致 URI 变成/admin//user/list - 闭包里又写了绝对路径(如
Route::get('/user/list', ...))→ 跳出分组,前缀失效 - 多个同名路由别名未加前缀,导致覆盖(如两个
article.index)
嵌套本身不难,难的是路径拼接和命名空间这两处静默失效点——它们不出错,但请求永远 404。


















