ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
> 中间件主要用于Controller的拦截处理,基于洋葱模式,如下图 ![](https://img.kancloud.cn/c6/6b/c66bbf9864f476c7b10e225575456818_914x569.png) > 执行顺序:Request -> Middleware 1 -> Middleware 2 -> Middleware 3 -> Middleware 2 -> Middleware 1 -> Response > 中间件有三种类型,他们的顺序:`全局中间件 -> 类级别中间件 -> 方法级别中间件` [TOC] ## 全局中间件 > 配置文件`/config/autoload/middlewares.php` ~~~ return [ // http 对应 config/autoload/server.php 内每个 server 的 name 属性对应的值,该配置仅应用在该 Server 中 'http' => [ // 数组内配置您的全局中间件,顺序根据该数组的顺序 YourMiddleware::class ], ]; ~~~ ## 定义局部中间件 ### 配置文件方式 > 配置文件`/config/routes.php` ~~~ use App\Middleware\FooMiddleware; use Hyperf\HttpServer\Router\Router; // 每个路由定义方法都可接收一个 $options 参数 Router::get('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [FooMiddleware::class]]); Router::post('/', [\App\Controller\IndexController::class, 'index'], ['middleware' => [FooMiddleware::class]]); Router::addRoute(['GET', 'POST', 'HEAD'], '/index', [\App\Controller\IndexController::class, 'index'], ['middleware' => [FooMiddleware::class]]); // 该 Group 下的所有路由都将应用配置的中间件 Router::addGroup( '/v2', function () { Router::get('/index', [\App\Controller\IndexController::class, 'index']); }, ['middleware' => [FooMiddleware::class]] ); ~~~ ### 注解方式 > 注解里含有Middlewares和Middleware两种注解,Middlewares可包含多个Middleware #### 类级别中间件 ~~~ namespace App\Controller; 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.'; } } ~~~ #### 方法级别中间件 > 类级别上的中间件会优先于方法级别的中间件 ~~~ namespace App\Controller; 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.'; } } ~~~ ## 生成中间件 ~~~ php ./bin/hyperf.php gen:middleware Auth/FooMiddleware ~~~ ~~~ 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 = true; if ($isValidToken) { return $handler->handle($request); } return $this->response->json( [ 'code' => -1, 'data' => [ 'error' => '中间里验证token无效,阻止继续向下执行', ], ] ); } } ~~~