前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hyperf 初体验-中间件

Hyperf 初体验-中间件

作者头像
hedeqiang
修改2020-01-11 13:58:00
1.3K2
修改2020-01-11 13:58:00
举报
文章被收录于专栏:LaravelCode

何为中间件

中间件主要用于编织从 请求(Request) 到 响应(Response) 的整个流程

程序员吐槽大会来解释中间件: 中间件就是,比如说马老师特别忙,每天很多人要见马老师,马老师不可能每个人都接待,很忙又不安全,这时候指定水彧来接待。所有人想找马老师都得先找水彧,马老师只跟水彧对接。这就是美曰其名的中间件。就是时代好了,以前这就叫太监...

生成中间件

代码语言:javascript
复制
php ./bin/hyperf.php gen:middleware Auth/FooMiddleware

将会生成 app\Middleware\Auth\FooMiddleware 中间件

使用中间件

我们拿官网的实例代码来测试.

代码语言:javascript
复制
<?php

declare(strict_types=1);

namespace App\Middleware\Auth;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class FooMiddleware implements MiddlewareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var RequestInterface
     */
    protected $request;

    /**
     * @var HttpResponse
     */
    protected $response;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // 根据具体业务判断逻辑走向,这里假设用户携带的token有效
        $isValidToken = false;
        if ($isValidToken) {
            return $handler->handle($request);
        }

        return $this->response->json(
            [
                'code' => -1,
                'data' => [
                    'error' => '中间里验证token无效,阻止继续向下执行',
                ],
            ]
        );
    }
}

分为全局中间件和局部中间件

全局中间件

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

代码语言:javascript
复制
<?php
return [
    // http 对应 config/autoload/server.php 内每个 server 的 name 属性对应的值,该配置仅应用在该 Server 中
    'http' => [
        // 数组内配置您的全局中间件,顺序根据该数组的顺序
        YourMiddleware::class
    ],
];
局部中间件

局部中间件可以通过配置文件或者注解定义

代码语言:javascript
复制
<?php
use App\Middleware\FooMiddleware;
use Hyperf\HttpServer\Router\Router;

// 每个路由定义方法都可接收一个 $options 参数
Router::get('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);
Router::post('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);
Router::put('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);
Router::patch('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);
Router::delete('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);
Router::head('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);
Router::addRoute(['GET', 'POST', 'HEAD'], '/index', [\App\Controller\IndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);

// 该 Group 下的所有路由都将应用配置的中间件
Router::addGroup(
    '/v2', function () {
        Router::get('/index', [\App\Controller\IndexController::class, 'index']);
    },
    ['middleware' => [ForMiddleware::class]]
);
通过注解定义

定义单个中间件

代码语言:javascript
复制
<?php

use App\Middleware\FooMiddleware;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;

/**
 * @AutoController()
 * @Middleware(FooMiddleware::class)
 */
class IndexController
{
    public function index()
    {
        return 'Hello Hyperf.';
    }
}

定义多个中间件

代码语言:javascript
复制
<?php

use App\Middleware\BarMiddleware;
use App\Middleware\FooMiddleware;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;

/**
 * @AutoController()
 * @Middlewares({
 *     @Middleware(FooMiddleware::class),
 *     @Middleware(BarMiddleware::class)
 * })
 */
class IndexController
{
    public function index()
    {
        return 'Hello Hyperf.';
    }
}

定义方法级别中间件

代码语言:javascript
复制
<?php

use App\Middleware\BarMiddleware;
use App\Middleware\FooMiddleware;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;

/**
 * @AutoController()
 * @Middlewares({
 *     @Middleware(FooMiddleware::class)
 * })
 */
class IndexController
{

    /**
     * @Middlewares({
     *     @Middleware(BarMiddleware::class)
     * })
     */
    public function index()
    {
        return 'Hello Hyperf.';
    }
}
测试中间件

我们通过配置文件路由的方式来定义局部中间件 config\route.php

代码语言:javascript
复制
<?php

declare(strict_types=1);

use App\Middleware\Auth\FooMiddleware;
use Hyperf\HttpServer\Router\Router;

Router::get('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [FooMiddleware::class]]);

然后访问路由

file
file

测试注解定义中间件

代码语言:javascript
复制
<?php

namespace App\Controller;

use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\Auth\FooMiddleware;

/**
 * @AutoController()
 * @Middleware(FooMiddleware::class)
 */
class IndexController extends Controller
{
    public function index()
    {
        return 'Hello Hyperf';
    }
}
file
file

注意必须引入中间件所在的命名空间

测试全局中间件 编辑 config/autoload/middlewares.php 文件

代码语言:javascript
复制
<?php

declare(strict_types=1);

use App\Middleware\Auth\FooMiddleware;

return [
    'http' => [
        FooMiddleware::class,
    ],
];

我们将控制器 通过注解定义的中间件删掉,然后重启,可以看到局部中间件也没有问题。

file
file

ok,以上就是走了一遍文档上的中间件,更多用法请参考 官方文档

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 何为中间件
  • 生成中间件
  • 使用中间件
    • 全局中间件
      • 局部中间件
        • 通过注解定义
      • 测试中间件
      相关产品与服务
      消息队列 TDMQ
      消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档