Hyperf 初體驗-中間件

  • 2019 年 12 月 17 日
  • 筆記

何為中間件

中間件主要用於編織從 請求(Request) 到 響應(Response) 的整個流程

程式設計師吐槽大會來解釋中間件: 中間件就是,比如說馬老師特別忙,每天很多人要見馬老師,馬老師不可能每個人都接待,很忙又不安全,這時候指定水彧來接待。所有人想找馬老師都得先找水彧,馬老師只跟水彧對接。這就是美曰其名的中間件。就是時代好了,以前這就叫太監…

生成中間件

php ./bin/hyperf.php gen:middleware Auth/FooMiddleware

將會生成 appMiddlewareAuthFooMiddleware 中間件

使用中間件

我們拿官網的實例程式碼來測試.

<?php    declare(strict_types=1);    namespace AppMiddlewareAuth;    use HyperfHttpServerContractRequestInterface;  use HyperfHttpServerContractResponseInterface as HttpResponse;  use PsrContainerContainerInterface;  use PsrHttpMessageResponseInterface;  use PsrHttpMessageServerRequestInterface;  use PsrHttpServerMiddlewareInterface;  use PsrHttpServerRequestHandlerInterface;    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 ,配置如下:

<?php  return [      // http 對應 config/autoload/server.php 內每個 server 的 name 屬性對應的值,該配置僅應用在該 Server 中      'http' => [          // 數組內配置您的全局中間件,順序根據該數組的順序          YourMiddleware::class      ],  ];

局部中間件

局部中間件可以通過配置文件或者註解定義

<?php  use AppMiddlewareFooMiddleware;  use HyperfHttpServerRouterRouter;    // 每個路由定義方法都可接收一個 $options 參數  Router::get('/', [AppControllerIndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);  Router::post('/', [AppControllerIndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);  Router::put('/', [AppControllerIndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);  Router::patch('/', [AppControllerIndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);  Router::delete('/', [AppControllerIndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);  Router::head('/', [AppControllerIndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);  Router::addRoute(['GET', 'POST', 'HEAD'], '/index', [AppControllerIndexController::class, 'index'], ['middleware' => [ForMiddleware::class]]);    // 該 Group 下的所有路由都將應用配置的中間件  Router::addGroup(      '/v2', function () {          Router::get('/index', [AppControllerIndexController::class, 'index']);      },      ['middleware' => [ForMiddleware::class]]  );
通過註解定義

定義單個中間件

<?php    use AppMiddlewareFooMiddleware;  use HyperfHttpServerAnnotationAutoController;  use HyperfHttpServerAnnotationMiddleware;    /**   * @AutoController()   * @Middleware(FooMiddleware::class)   */  class IndexController  {      public function index()      {          return 'Hello Hyperf.';      }  }

定義多個中間件

<?php    use AppMiddlewareBarMiddleware;  use AppMiddlewareFooMiddleware;  use HyperfHttpServerAnnotationAutoController;  use HyperfHttpServerAnnotationMiddleware;    /**   * @AutoController()   * @Middlewares({   *     @Middleware(FooMiddleware::class),   *     @Middleware(BarMiddleware::class)   * })   */  class IndexController  {      public function index()      {          return 'Hello Hyperf.';      }  }

定義方法級別中間件

<?php    use AppMiddlewareBarMiddleware;  use AppMiddlewareFooMiddleware;  use HyperfHttpServerAnnotationAutoController;  use HyperfHttpServerAnnotationMiddleware;  use HyperfHttpServerAnnotationMiddlewares;    /**   * @AutoController()   * @Middlewares({   *     @Middleware(FooMiddleware::class)   * })   */  class IndexController  {        /**       * @Middlewares({       *     @Middleware(BarMiddleware::class)       * })       */      public function index()      {          return 'Hello Hyperf.';      }  }

測試中間件

我們通過配置文件路由的方式來定義局部中間件 configroute.php

<?php    declare(strict_types=1);    use AppMiddlewareAuthFooMiddleware;  use HyperfHttpServerRouterRouter;    Router::get('/', [AppControllerIndexController::class, 'index'], ['middleware' => [FooMiddleware::class]]);

然後訪問路由

測試註解定義中間件

<?php    namespace AppController;    use HyperfHttpServerAnnotationAutoController;  use HyperfHttpServerAnnotationMiddleware;  use AppMiddlewareAuthFooMiddleware;    /**   * @AutoController()   * @Middleware(FooMiddleware::class)   */  class IndexController extends Controller  {      public function index()      {          return 'Hello Hyperf';      }  }

注意必須引入中間件所在的命名空間

測試全局中間件 編輯 config/autoload/middlewares.php 文件

<?php    declare(strict_types=1);    use AppMiddlewareAuthFooMiddleware;    return [      'http' => [          FooMiddleware::class,      ],  ];

我們將控制器 通過註解定義的中間件刪掉,然後重啟,可以看到局部中間件也沒有問題。

ok,以上就是走了一遍文檔上的中間件,更多用法請參考 官方文檔

(adsbygoogle = window.adsbygoogle || []).push({});