全局中间件之 CheckForMaintenanceMode
简介
上一章,我们看了 Pipeline 管道操作如何实现请求穿透中间件。从本章开始,我们将逐一介绍 Laravel 五大全局中间件对请求做了什么。。
做了什么:首先,应该要弄清如何做的,上一章我有提到过,就是以请求和洋葱作为参数,执行中间件的 handle 方法。
先看一下五大中间件有哪些
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
这一章,我们看一下第一个中间 App\Http\Middleware\CheckForMaintenanceMode
。
关于 App\Http\Middleware\CheckForMaintenanceMode
从字面意思不难看出,这个中间件是检测我们整个项目有没有处于 维护模式。
-
关于维护模式,下面是一段官方文档的说明:
-
开启维护模式
php artisan down
这条命令做了什么呢?
这个要看
Illuminate\Foundation\Console\DownCommand
,此类就是php artisan down
所要运行的命令类<?php namespace Illuminate\Foundation\Console; use Illuminate\Console\Command; use Illuminate\Support\InteractsWithTime; class DownCommand extends Command { use InteractsWithTime; /** * 命令签名:就是执行 php artisan down 后面加的命令参数 */ protected $signature = 'down {--message= : The message for the maintenance mode. } {--retry= : The number of seconds after which the request may be retried.} {--allow=* : IP or networks allowed to access the application while in maintenance mode.}'; /** * down 命令的描述 * * Put the application into maintenance mode : 意思是开启 Laravel 应用的维护模式 */ protected $description = 'Put the application into maintenance mode'; /** * 这个就是执行 php artisan down 命令实际运行的逻辑代码 */ public function handle() { // 在 storage/framework/ 目录下写入 down 文件,格式是 getDownFilePayload 方法的返回。 file_put_contents( storage_path('framework/down'), json_encode($this->getDownFilePayload(), JSON_PRETTY_PRINT) ); // 在屏幕打印成功的消息 $this->comment('Application is now in maintenance mode.'); } /** * down 文件的内容格式 */ protected function getDownFilePayload() { return [ 'time' => $this->currentTime(), 'message' => $this->option('message'), 'retry' => $this->getRetryTime(), 'allowed' => $this->option('allow'), ]; } /** * 获取浏览器刷新前应该等待的秒数。 */ protected function getRetryTime() { $retry = $this->option('retry'); return is_numeric($retry) && $retry > 0 ? (int) $retry : null; } }
通过 down 命令的源码我们不难看出,它的作用无非就是在
storage/framework/
目录下创建叫down
文件,里面的内容有:time
开启维护的时间message
页面的提示信息retry
浏览器每隔多长时间刷新一次allowed
允许进入应用的 IP 地址组
说百遍,道万千,不如一张图----->
-
关闭维护模式
php artisan up
简单,不就是删掉
down
文件吗。。。这个源码不需要看了吧,不需要看了吧,不回答,就是默认喽。。好,那就不看了。。
那么,我们开启维护模式了,Laravel 又是如何知道呢(好能噢\~\~\~\~)
这个就是
App\Http\Middleware\CheckForMaintenanceMode
中间件的作用了,它会知道我们到底有没有开维护模式。(好能噢\~\~\~\~)
看源码:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
class CheckForMaintenanceMode extends Middleware
{
/**
* 这里是定义 路由除外,意思是除了这些路由正常进入应用,其它路由过来甩它一脸。
*
* @var array
*/
protected $except = [
//
];
}
咦? handle 方法呢。。哦,原来这是子类,那肯定是在父类了,不废话了直接上父类的 handle 方法
public function handle($request, Closure $next)
{
// if 就是看有没有 down 文件;有则执行 if 里面的代码
if ($this->app->isDownForMaintenance()) {
// 将 down 文件里面的json数据转换成数组
$data = json_decode(file_get_contents($this->app->storagePath().'/framework/down'), true);
// 看一下数组里面的 allowed 与请求过来的 IP 匹配吗,匹配就进入应用
if (isset($data['allowed']) && IpUtils::checkIp($request->ip(), (array) $data['allowed'])) {
return $next($request);
}
// 这个就是看一下子类定义的除外路由,有没有与请求的路由匹配上,匹配上就进入应用
if ($this->inExceptArray($request)) {
return $next($request);
}
// 经过披荆斩棘,一路坎坷,没有一个符合条件,不好意思,甩你一脸狗粮(维护页面),难受不。。。哈哈哈
throw new MaintenanceModeException($data['time'], $data['retry'], $data['message']);
}
return $next($request);
}
代码里面说的很明白了,,再深了的内容,比如如何判断有米有 down 文件,就请各位小伙伴,自己走进去一探究竟了哈,我这里就不看了。
本篇如有错误、不当或者需补充的内容,请各位同僚多提宝贵意见。