一、加载中间件
上一篇分析了应用的初始化,也就是对 Http 类的 run() 方法里面调用的 runWithRequest () 方法的第一行代码 $this->initialize() 的展开分析。让我们再看一眼 runWithRequest () 方法的前几行:
protected function runWithRequest(Request $request)
{
$this->initialize();
// 加载全局中间件
$this->loadMiddleware();
.
.
.
应用初始化后,接下来开始处理中间件。
中间件类的初始化
loadMiddleware 方法:
protected function loadMiddleware(): void
{
if (is_file($this->app->getBasePath() . 'middleware.php')) {
$this->app->middleware->import(include $this->app->getBasePath() . 'middleware.php');
}
}
依然是百用不厌的套路,通过 $this->app->middleware 来实例化中间件并获取其实例。
导入中间件
通过 $this->app->middleware 得到 Middleware 类的实例后,接着程序调用 import 方法,传入从「app」目录下的「middleware.php」文件中读取的数据。该文件的原始内容如下(原来全部注释掉的):
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
\think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class,
// 页面Trace调试
\think\middleware\TraceDebug::class,
];
这里为了研究中间件是如何加载的,先去掉两个注释,也就是添加两个中间件。接下来看 import 方法:
public function import(array $middlewares = [], string $type = 'global'): void
{
foreach ($middlewares as $middleware) {
$this->add($middleware, $type);
}
}
该方法传入一个中间件的数组和一个中间件类型,默认为 global,关键是里面的 add 方法。跳到 add 方法:
public function add($middleware, string $type = 'route'): void
{
if (is_null($middleware)) {
return;
}
$middleware = $this->buildMiddleware($middleware, $type);
if (