11、Hyperf 3 快速使用 - 中间件的使用

作者: 温新

分类: 【Hyperf 3 基础系列】

阅读: 380

时间: 2023-04-25 12:25:33

hi,我是温新,一名 PHPer

Hypref 版本:Hyperf 3.0

学习目标:l了解中间件原理,掌握中间件的使用

本文主要摘自官方文档。

中间件原理

中间件的本质是一个 洋葱模型 。主要用于从 请求(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) 进行处理了,内核 通常是由框架负责实现的,而其它的就由您来编排了。

从这个过程来看,其实有点像冒泡,把它当作冒泡来理解可能还简单些。

中间件类型

Hyperf 中,有全局中间件、局部中间件、方法级别的中间件。如果都定义了这些中间件,执行顺序为:全局中间件 -> 类级别中间件 -> 方法级别中间件

全局中间件的使用

第一步:创建一个全局中间件

<?php
// App\Middleware\Api\ApiMiddleware.php
    
namespace App\Middleware\Api;

use PhpParser\Node\Stmt\Return_;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\HttpServer\Contract\RequestInterface;
class ApiMiddleware implements MiddlewareInterface
{

    public function __construct(
        protected ContainerInterface $container,
        protected \Hyperf\HttpServer\Contract\ResponseInterface $response,
        protected RequestInterface $request
    )
    {
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        echo '全局中间间' . PHP_EOL;
        // 业务逻辑处理
        
        // $response = $handler->handle($request);
		// 中间位置也可以处理
        // return $response
        return $handler->handle($request);
    }
}

第二步:注册全局中间件

<?php
// config/autoload/middlewares.php
    
declare(strict_types=1);

return [
    'http' => [
        \App\Middleware\Api\ApiMiddleware::class
    ],
];

这样,中间件就定义完成了,

局部中间件的使用

方式一:路由中使用中间件

第一步:创建一个控制器

<?php
//  App\Controller\Test\TestController.php
namespace App\Controller\Test;

class TestController
{
    public function index()
    {
        echo 'Test 控制器' . PHP_EOL;
        return 'test';
    }
}

第二步:定义路由

Router::get('/test', [\App\Controller\Test\TestController::class, 'index'], ['middleware'=>[\App\Middleware\Api\RouterMiddleware::class]]);

方式二:通过注解使用中间件

<?php
// App\Controller\Test\PostController.php
    
namespace App\Controller\Test;

use App\Middleware\Api\PostMiddleware;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;

#[AutoController]
#[Middleware(PostMiddleware::class)]
class PostController
{
    public function index()
    {
        echo 'Post 控制器' . PHP_EOL;

        return 'post index';
    }
}

方式三:通过注解方式定义方法界别的中间件

<?php
// App\Controller\Test\VideoController.php
    
namespace App\Controller\Test;

use App\Middleware\Api\VideoMiddleware;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;

#[AutoController]
class VideoController
{
    #[Middleware(VideoMiddleware::class)]
    public function index()
    {
        echo 'Video 控制器' . PHP_EOL;
        return 'Video 控制器';
    }

    public function show()
    {
        return 'show';
    }
}
请登录后再评论