Skip to content

中间件

中间件一般用于拦截请求或者响应。例如执行控制器前统一验证用户身份,在用户未登录时跳转到登录页面,例如记录接口请求日志等等。

运行逻辑

一个中间件可以包括 before()after() 两个方法,before() 方法在控制器初始时执行,after() 方法在控制器响应后执行。

注意

after()中的代码在控制器中使用 $this->succes()$this->error()$this->rawOutput()响应后,以及$this->redirect()响应前执行。

中间件配置

中间件配置在 config/middleware.php 文件中,如果如下:

php
<?php

return [
    //    '' => [
    //        //全局中间件
    //        'AccessControl',
    //    ],
    '/admin' => [
        "admin",
    ],
    '/merchant/test' => [
        "admin",
    ],
];

每个数组项为一个路由前缀,对应的要执行中间件列表。 一个 URI 路由可以配置多个中间件,中间件的执行顺序按照配置的顺序执行 before() 方法,并按逆序执行 after() 方法。

中间件编写

每个中间件放置在 app/middleware 目录下,文件名和类名和配置文件中的一致,类的命名空间应为 app\middleware,类包含 public 的 before()after() 方法。

一个中间件的示例:

php
<?php

namespace app\middleware;

use framework\support\Redis;
use framework\support\Request;

class admin
{
    function before()
    {

        $request = request();
        $authHeader = $request->header("Authorization");
        $token = null;
        if ($authHeader) {
            $arr = explode(' ', $authHeader);
            if (count($arr) > 1) {
                $token = $arr[1];
            } else {
                $token = $authHeader;
            }
        }
        $isExistToken = Redis::get("admin_" . $token);
        if (!$isExistToken) {
            Response::Error(401, "令牌过期");
            return false;
        }
    }

    function after()
    {
        //记录管理员操作日志;
    }
}

中间件的返回值

如果一个中间件的 before() 方法返回 false,则后续的中间件和控制器都不会执行,直接返回错误响应。