ThinkPHP6.1路由分组嵌套是扁平叠加而非树状继承,外层中间件、前缀等不自动传递至内层,须显式声明或改用路径前缀;三层以上嵌套应拆为单层+完整前缀,域名分组内禁止嵌套路由。

ThinkPHP6.1中路由分组嵌套不是树状继承结构,而是扁平叠加关系,外层分组的中间件、前缀、参数约束等不会自动传递到内层分组,必须显式重复声明或改用路径前缀统一管理,否则请求会绕过预期拦截逻辑。
嵌套分组的正确写法
Route::group('admin', function () {
Route::get('index', 'Admin/index');
Route::group('user', function () {
Route::get('list', 'User/list');
Route::get('add', 'User/add');
});
});
这段代码注册了三条路由:/admin/index、/admin/user/list、/admin/user/add。注意:内层 user 分组的路径是拼接到外层 admin 后的,但控制器命名空间仍为 app\controller\User,不会自动变成 app\controller\Admin\User。
这一步操作起来很简单,直接把子分组写进外层闭包即可。
立即学习“PHP免费学习笔记(深入)”;
中间件在嵌套分组中的绑定方式
方法一:每层分组独立绑定(推荐)
Route::group('admin', function () {
Route::get('index', 'Admin/index');
Route::group('user', function () {
Route::get('list', 'User/list');
})->middleware('auth'); // 仅作用于 /admin/user/* 路由
})->middleware('check_domain'); // 仅作用于 /admin/index 及该分组顶层路由
方法二:统一前缀 + 条件判断(更可控)
Route::group('admin', function () {
Route::get('index', 'Admin/index');
Route::group('user', function () {
Route::get('list', 'User/list');
});
})->prefix('admin')->middleware('auth'); // 所有 /admin/* 路由都走 auth
【嵌套分组不自动继承外层 middleware()】——这是最常被忽略的一点。若只在外层调用 ->middleware('auth'),内层分组定义的路由将完全不受控。
避免嵌套三层以上分组
第一步:检查当前路由结构是否已出现三层嵌套,例如:
Route::group('api', function () {
Route::group('v1', function () {
Route::group('user', function () {
Route::get('profile', 'User/profile');
});
});
});
第二步:将第三层拆出,改为路径前缀方式:
Route::group('api/v1/user', function () {
Route::get('profile', 'User/profile');
});
第三步:统一挂载中间件:
Route::group('api/v1/user', function () {
Route::get('profile', 'User/profile');
})->middleware(['auth', 'scope:user']);
嵌套超过两层后,调试时很难快速定位哪一层漏绑了中间件,也容易因 prefix 拼接混乱导致 URL 匹配失败。改成单层分组+完整路径前缀,可读性和维护性明显提升。
域名分组内禁止嵌套路由分组
Route::domain('api.example.com', function () {
Route::group('v1', function () {
Route::get('user', 'Api/User/index');
});
});
这种写法看似合理,但实际无效。【域名绑定优先级高于路径分组,嵌套会导致内部 group() 被忽略】。所有路由都会匹配到 api.example.com/v1/user,但中间件、prefix、pattern 等配置均不生效。
正确做法是去掉内层 group,直接在域名闭包里注册带前缀的路由:
Route::domain('api.example.com', function () {
Route::get('v1/user', 'Api/User/index')->middleware('cors');
});



















