thinkphp路由中间件必须显式绑定,无自动识别机制;单个路由用->middleware()链式调用,分组路由用route::group()->middleware()统一绑定;权限标识应通过->option()注入,中间件中用$request->rule()->getoption()获取;获取完整操作方法应使用$request->rule()->getaction()。

ThinkPHP 的路由中间件不是靠“注册到路由上”实现的,而是通过在路由定义时显式绑定中间件——它没有“路由级中间件”的独立概念,只有“路由绑定中间件”这一种可靠方式。想靠中间件自动识别当前匹配的路由再做权限判断,容易漏掉闭包路由、资源路由或 group 嵌套场景。
如何给单个路由绑定中间件
最直接的方式是在 route/app.php 中定义路由时用 middleware 方法链式调用:
// route/app.php
use think\facade\Route;
Route::get('admin/user/list', 'admin.UserController@list')
->middleware('check_auth'); // 绑定中间件名(字符串)
注意:check_auth 是你在 app/middleware.php 或中间件类中注册的别名,不是类全名;如果没注册别名,得写完整类名:\app\middleware\CheckAuth::class。
常见错误:把中间件名写成未注册的字符串,运行时报 Middleware not found: xxx;或者误用 ->middleware(['check_auth']) 传数组却只绑一个,虽不报错但冗余。
如何给路由分组统一绑定权限中间件
后台模块、API 版本前缀这类场景,用 group + middleware 最省事:
Route::group('admin', function () {
Route::get('user/list', 'admin.UserController@list');
Route::post('user/add', 'admin.UserController@add');
})->middleware('check_auth');
这样比每个路由单独写更安全,也避免遗漏。但要注意:group 的中间件是“前置执行”,不会因为子路由用了 allowCrossDomain 等其他中间件就跳过权限检查。
关键点:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- group 的中间件对所有子路由生效,包括闭包路由和资源路由
- 如果子路由又单独调用了
->middleware(),会叠加执行(不是覆盖),顺序按绑定先后 - 资源路由(
Route::resource())必须在 group 内定义,否则 group 中间件不生效
为什么不能在中间件里靠 $request->url() 做路由级判断
有人试图在中间件里解析当前 URL 字符串,再查配置表做权限控制,这会导致三个问题:
第一,URL 可能带参数(如 /user/edit/123),硬匹配会失败;第二,ThinkPHP 路由支持变量规则([:id])、正则约束,字符串比对无法还原原始路由定义;第三,闭包路由和动态注册路由根本没“名称”,无法反查。
正确做法是:在路由定义阶段就打上权限标识,比如用 option 注入权限码:
Route::get('admin/log', 'admin.LogController@index')
->option(['auth_rule' => 'log:read']);
然后在中间件里用 $request->rule()->getOption('auth_rule') 拿到它——这才是 ThinkPHP 原生支持的、可靠的路由元数据获取方式。
中间件中如何获取当前路由的真实操作方法
权限系统常需知道“用户是否拥有访问 admin.UserController@delete 的权限”,但 $request->action() 返回的是方法名(如 delete),不带控制器。可靠方式是组合使用:
$controller = $request->controller(); // 返回 'User' $action = $request->action(); // 返回 'delete' $module = $request->module(); // 返回 'admin' $fullAction = $module . '.' . $controller . '@' . $action; // 'admin.User@delete'
注意:$request->controller() 返回值默认首字母大写,但实际类名可能驼峰(UserList),所以更稳妥的是从路由规则里取原始调度信息:$request->rule()->getAction()(返回完整类方法字符串,如 app\controller\admin\UserController@list)。
这个细节在 RBAC 权限校验时特别关键——控制器名大小写、命名空间层级稍有偏差,权限就判错。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










