Menu

全局中间件之 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

从字面意思不难看出,这个中间件是检测我们整个项目有没有处于 维护模式

  • 关于维护模式,下面是一段官方文档的说明:

    https://learnku.com/docs/laravel/5.6/configuration/1353#972c4c

  • 开启维护模式

    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 地址组

    说百遍,道万千,不如一张图----->

    file

  • 关闭维护模式

    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 文件,就请各位小伙伴,自己走进去一探究竟了哈,我这里就不看了。

本篇如有错误、不当或者需补充的内容,请各位同僚多提宝贵意见。

本文章首发在 LearnKu.com 网站上。
上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~