ThinkPHP 不支持运行时动态注册中间件,所有中间件必须在 app/middleware.php 中静态声明并返回类名数组;不存在 Middleware 门面或 register/bind 方法,所谓“动态”只能在 handle() 内通过请求条件判断实现。

ThinkPHP 没有 Middleware 门面,你不能用 Middleware::add() 或类似方式动态注册中间件。 所有中间件必须在启动阶段静态声明,运行时无法通过门面“添加”新中间件。
中间件注册只发生在 app/middleware.php(或模块级 middleware.php)
框架启动时,仅读取 app/middleware.php 返回的数组(或对应应用/模块下的同名文件),逐个实例化并加入中间件栈。这个过程不可逆、不可追加。
- 该文件必须存在且 返回一个类名数组,例如:
return [\app\middleware\Auth::class, \think\middleware\Lang::class]; - 写
return null、echo、die或返回非数组值,会导致中间件完全不加载 - 多应用模式下,
app/middleware.php是全局配置,各应用需在自己目录(如app/admin/middleware.php)单独定义
别名注册不是门面,是配置映射
你可能看到过 'auth' => \app\middleware\Auth::class 这样的写法,它出现在 config/middleware.php(TP5.1)或通过 app/middleware.php 的别名数组(TP6+),但这只是字符串到类的映射表,不是可调用的门面对象。
- 路由中写
->middleware('auth'),本质是框架查这张表,再替换为真实类名 - 没有
Middleware::bind()、Middleware::register()等方法,Middleware类本身在 ThinkPHP 中不存在 - 试图
use think\facade\Middleware会报错:Classthink\facade\Middlewarenot found
想“动态”控制中间件?只能靠条件分支
所谓“动态”,实际是在中间件内部做判断,而非注册时增删。比如权限中间件里跳过某些路径:
立即学习“PHP免费学习笔记(深入)”;
public function handle($request, \Closure $next)
{
// 排除登录页、验证码等免检路径
if (in_array($request->path(), ['login', 'captcha', 'api/public'])) {
return $next($request);
}
if (!session('user_id')) {
return redirect('/login');
}
return $next($request);
}
- 所有逻辑必须塞进
handle()方法里,依赖$request做运行时判断 - 不能在中间件里调用
app()->middleware->add()—— 框架根本不提供这个能力 - 若需按用户角色启用不同中间件组合,应提前在
app/middleware.php中全部注册,再靠内部条件分流
真正容易被忽略的是:中间件注册时机极早,一旦请求开始,中间件栈就已冻结。任何想“中途插入”或“运行时启用”的想法,都得回归到 handle() 内部的 if/else 上,而不是寻找不存在的门面 API。



















