中间件不执行的根本原因是加载链断裂:文件路径或命名空间不匹配(必须为app\http\middleware)、application/middleware.php缺失或返回非法值、handle方法签名错误、未在路由或控制器中显式注册。

中间件文件写好了、注册了、也加了 return $next($request),但就是不执行——八成是没走到加载环节,不是逻辑错,是链路断在了最前面。
中间件类文件放错位置或命名空间不匹配
ThinkPHP 5.1.27 LTS 默认只扫描 app\http\middleware 命名空间下的类,且要求文件路径与命名空间严格对应。
- 生成命令必须用
php think make:middleware AuthCheck,它会自动建在application/http/middleware/AuthCheck.php(注意是application/,不是app/) - 类文件开头必须是
namespace app\http\middleware;,不能写成app\middleware或application\http\middleware - 别手动建在
app/middleware/下——这个目录在 5.1.27 LTS 中默认不被扫描 - 文件名必须和类名完全一致(大小写敏感),
Authcheck.php≠AuthCheck.php
app/middleware.php 不存在、返回值非法或被提前终止
这是中间件“静默失效”最常见原因:框架根本没读到你的类。
-
application/middleware.php文件必须存在,且返回一个数组,例如:return [\app\http\middleware\AuthCheck::class]; - 不能有
echo、var_dump、BOM 头或任何输出;哪怕多一个空格,PHP 解析失败,整个文件返回null,框架就当没这回事 - 不能删掉这个文件,也不能改名为
middleware.php.bak——框架只认这个名字 - 数组元素必须是完整类名字符串,
'app\http\middleware\AuthCheck'和\app\http\middleware\AuthCheck::class都可以,但不能漏掉app\前缀
handle() 方法签名或返回值错误
哪怕只错一个参数,中间件也会跳过执行,且不报错。
- 方法签名必须是
public function handle($request, \Closure $next),少一个参数、类型不对、顺序颠倒都不行 - 必须有
return,且返回值必须是think\Response实例;return null、return 'ok'、echo 'forbidden'; die();都会导致请求中断且无提示 - 放行写法统一用:
return $next($request); - 如需传参(比如路由里写
->middleware(AuthCheck::class, 'admin')),handle()必须多接一个参数:handle($request, \Closure $next, $role)
路由或控制器级注册时漏掉 middleware() 链式调用
全局注册靠 application/middleware.php,局部注册必须显式声明,否则框架完全无视。
- 路由注册示例:
Route::get('admin/user', 'Admin/User/index')->middleware(\app\http\middleware\AuthCheck::class);—— 少了->middleware(...)这一环,中间件不会触发 - 控制器内注册要写在构造函数:
$this->middleware(\app\http\middleware\AuthCheck::class);,不能写在任意方法里 - 控制器方法级限制需用数组指定:
$this->middleware(\app\http\middleware\AuthCheck::class, ['only' => ['edit', 'delete']]);
真正容易被忽略的是:中间件的执行依赖整个加载链的完整性。任何一个环节——文件路径、命名空间、配置文件返回值、方法签名、调用方式——只要有一个字符偏差,它就彻底不走。不要猜逻辑,先用 var_dump(class_exists('\app\http\middleware\AuthCheck')) 和 var_dump(include_once 'application/middleware.php') 直接验证是否被识别和加载。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











