thinkphp6中间件拦截失败的核心原因是未注册或未执行:app/middleware.php文件缺失、返回非数组、类名缺命名空间、多应用下路径错误、路由未显式调用middleware()、handle()未return response实例,或session/token访问时机不当。

ThinkPHP6中间件拦截请求失败,核心问题往往不是逻辑写错了,而是它根本没进请求处理流程——连执行机会都没有。
中间件压根没注册进去
app/middleware.php 文件必须存在,且返回一个包含完整命名空间类名的数组。常见错误包括:
- 文件被删、重命名,或内容为空、返回 null、echo 输出导致解析中断
- 写了 return ['Stats'] 或 return [Stats::class],漏了反斜杠,正确写法是 \app\middleware\Stats::class
- 多应用模式下(如启用 app/multi_app),还在根目录 app/middleware.php 注册,实际应放在 app/admin/middleware.php 并用 \app\admin\middleware\Stats::class
- 文件开头有 BOM 或空白行,PHP 解析失败,返回非数组
路由绑定漏掉了 middleware()
全局中间件只对“兜底请求”生效,API 或后台接口这类目标明确的请求,必须显式挂载:
- 正确写法:Route::group('api', function () { ... })->middleware(\app\middleware\Stats::class);
- 错误写法:分组里定义了路由,但没加 ->middleware(),中间件完全不触发
- 资源路由 Route::resource('post', 'PostController') 不继承控制器里的 $this->middleware(),每个动作都得单独指定,或改用分组绑定
handle() 方法没返回 Response 实例
这是最隐蔽也最致命的问题:末尾没 return,PHP 默认返回 null,框架当成「中断请求」,后续全跳过:
- 签名必须严格为 handle($request, \Closure $next),不能少参数
- 放行必须写 return $next($request),只写 $next($request) 不生效
- 拦截时要返回响应实例,比如 return json(['code'=>403]) 或 abort(403),不能用 die/exit
权限校验时机不对,Session 或 Token 拿不到
中间件默认拿不到已初始化的 Session 或 Auth,尤其在预检请求(OPTIONS)或 CLI 场景中:
- 别直接调 session('user_id'),改用 $request->session()->get('user_id')
- 带 credentials 的跨域请求,OPTIONS 不带 Cookie,需单独放行,再在正式请求中校验 Token
- 权限判断建议抽离为独立服务,避免中间件耦合 DB 查询;若必须查库,确保该中间件注册位置靠后(如在 core 之后)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











