中间件别名必须在config/middleware.php中定义,而非app/middleware.php;该文件需返回含'alias'键的数组,值为带完整命名空间的类常量(如app\middleware\Auth::class),且须执行php think clear:config清除配置缓存。

中间件别名必须在 config/middleware.php 里定义,不是 app/middleware.php
很多同学一上来就往 app/middleware.php 里写 return ['auth' => app\middleware\Auth::class];,结果死活不生效。这是因为 ThinkPHP 6.0+(含 8.0)已将别名注册统一收口到 config/middleware.php —— 这个文件默认存在,但内容为空或仅含注释。你得手动补全结构:
-
config/middleware.php必须返回一个数组,且必须包含'alias'键 - 别名值只能是类名字符串或
::class常量,不能是闭包或实例 - 类名必须带完整命名空间,比如
app\middleware\Auth::class,不能写成Auth::class - TP8.0 要求类文件名与类名严格一致(
Auth.php里必须是class Auth),否则别名解析失败且无提示
->middleware('auth') 中的 'auth' 是别名,不是类名或文件名
路由或控制器里写的字符串,只对应 config/middleware.php 中 'alias' 数组的键。它和实际类名、文件名完全解耦——你可以把 app\middleware\JwtCheck::class 映射为 'auth',也可以映射为 'guard',只要别名唯一、不冲突就行。
- 多个中间件共用一个别名?不行,
'alias'的 value 必须是单个类(TP6/8 不支持别名指向数组) - 想批量绑定一组中间件?用中间件分组,而不是复用别名;分组需在
'alias'下额外声明,例如'api_auth' => ['auth', 'throttle'](需自行实现分组解析逻辑,框架不原生支持) - 别名大小写敏感:
'Auth'和'auth'是两个不同别名
别名注册后不生效?先查这三处硬性条件
别名写对了,但 ->middleware('auth') 仍报 Middleware not found: auth,大概率卡在这几个地方:
-
config/middleware.php没有被正确加载:确认该文件真实存在且 PHP 语法合法(常见于末尾多逗号、漏分号) - 中间件类本身无法自动加载:运行
php think optimize:schema或检查composer dump-autoload是否执行过;类名拼错、命名空间错位都会导致反射失败 - TP8.0 强制要求中间件类实现
think\contract\MiddlewareInterface,且handle()方法必须标注返回类型: \think\Response;漏掉任一,别名解析阶段就静默跳过 - 缓存未清除:修改
config/middleware.php后,执行php think clear:config,否则旧配置仍在内存中
别名和全局中间件注册是两套机制,别混用
config/middleware.php 的 'alias' 只管“名字怎么叫”,而全局中间件列表(即请求入口自动执行的那些)要另外配——它在同一个文件里用 'priority' 或直接平铺数组声明。例如:
立即学习“PHP免费学习笔记(深入)”;
return [
'alias' => [
'auth' => app\middleware\Auth::class,
'log' => app\middleware\RequestLog::class,
],
'priority' => [
think\middleware\SessionInit::class,
app\middleware\Auth::class, // 这里写的是类名,不是别名
],
];
注意:'priority' 里填的是类名,不是别名;别名只服务于路由/控制器级的 ->middleware('xxx') 调用。两者路径不同、用途不同、解析时机也不同。
最易忽略的一点:TP8.0 禁用所有闭包中间件,哪怕你在路由里写 ->middleware(function($req, $next){...}),也会直接抛错——别名机制只面向类,闭包连注册入口都没有。



















