八:中间件
一:原理:
中间件主要用于编织从 请求(Request) 到 响应(Response) 的整个流程,通过对多个中间件的组织,使数据的流动按我们预定的方式进行,中间件的本质是一个 洋葱模型,我们通过一个图来解释它:

图中的顺序为按照 Middleware 1 -> Middleware 2 -> Middleware 3 的顺序组织着,我们可以注意到当中间的横线穿过 内核 即 Middleware 3 后,又回到了 Middleware 2,为一个嵌套模型,那么实际的顺序其实就是:Request -> Middleware 1 -> Middleware 2 -> Middleware 3 -> Middleware 2 -> Middleware 1 -> Response
重点放在 核心 即 Middleware 3,它是洋葱的分界点,分界点前面的部分其实都是基于 请求(Request) 进行处理,而经过了分界点时,内核 就产出了 响应(Response) 对象,也是 内核 的主要代码目标,在之后便是对 响应(Response) 进行处理了,内核 通常是由框架负责实现的,而其它的就由您来编排了。
二:定义全局中间件
全局中间件只可通过配置文件的方式来配置,配置文件位于 config/autoload/middlewares.php ,配置如下:

只需将您的全局中间件配置在该文件及对应的 Server Name 内,即该 Server 下的所有请求都会应用配置的全局中间件
三:定义局部中间件
当我们有些中间件仅仅面向某些请求或控制器时,即可将其定义为局部中间件,可通过配置文件的方式定义或注解的方式;
通过命令生成中间件 命令 php bin/hyperf.php gen:middleware FooMiddleware

3.1:通过注解定义
在通过注解定义路由时,您仅可通过注解的方式来定义中间件,对中间件的定义有两个注解,分别为:
(1):@Middleware 注解为定义单个中间件时使用,在一个地方仅可定义一个该注解,不可重复定义
(2):@Middlewares 注解为定义多个中间件时使用,在一个地方仅可定义一个该注解,然后通过在该注解内定义多个 @Middleware 注解实现多个中间件的定义





按照注入的顺序执行 先输出1;然后调用handle的时候就交给了下个顺序的中间件;
输出2,然后再调用handle的时候就交给了下个顺序的中间件;输出3;
由于顺序中间件只编排了三个中间件;然后再调用handle的时候就交给了由
Hyperf提供的一个核心中间件;核心中间件会最终产出$response这个对象;
输出6;然后再顺序执行最近一次执行的Middleware中间件;
该$response对象就是对应的中间件对象;
不难看出,假设我们根据返回的$response来做逻辑的判断和处理,
我们写到$response=$handler->handle($request)的上面,也就是echo1的代码块区域即可;
假设我们要对$response对象进行改写,那么我们在$response=$handler->handle($request)的
下方去做处理;

·


定义方法级别的中间件
您只需将注解直接定义到方法上即可。
类级别上的中间件会优先于方法级别的中间件,我们通过代码来举例一下:



3.2:通过配置文件定义
在使用配置文件定义路由时,您仅可通过配置文件来定义对应的中间件,局部中间件的配置将在路由配置上完成。Hyperf\HttpServer\Router\Router 类的每个定义路由的方法的最后一个参数 $options 都将接收一个数组,可通过传递键值 middleware 及一个数组值来定义该路由的中间件,我们通过几个路由定义来演示一下:

四:定义全局中间件
全局中间件只可通过配置文件的方式来配置,配置文件位于 config/autoload/middlewares.php ,配置如下:

五:中间件的执行顺序
我们从上面可以了解到总共有 3 种级别的中间件,分别为 全局中间件、类级别中间件、方法级别中间件,如果都定义了这些中间件,执行顺序为:全局中间件 -> 类级别中间件 -> 方法级别中间件。
六:全局更改请求和响应对象
首先,在协程上下文内是有存储最原始的 PSR-7 请求对象 和 响应对象 的,且根据 PSR-7 对相关对象所要求的 不可变性(immutable),也就意味着我们在调用 $response = $response->with***() 所调用得到的 $response,并非为改写原对象,而是一个 Clone 出来的新对象,也就意味着我们储存在协程上下文内的 请求对象 和 响应对象 是不会改变的,那么当我们在中间件内的某些逻辑改变了 请求对象 或 响应对象,而且我们希望对后续的 非传递性的 代码再获取改变后的 请求对象 或 响应对象,那么我们便可以在改变对象后,将新的对象设置到上下文中,如代码所示:





浙公网安备 33010602011771号