熊熊出没 发表于 2024-8-17 17:01:43

Hyperf 安装,利用,

安装,

一般开发都是windows,所以用虚拟机或docker
利用

启动

php bin/hyperf.php start
https://i-blog.csdnimg.cn/direct/922d2fa1e25240528a0958456c1e4195.png
假如出现端口被占用,下面的处理方法

[*]检察9501端口那个进程在占用
netstat -anp|grep 9501
https://i-blog.csdnimg.cn/direct/de8ca57406bc48749556e6088b006cad.png
2. kill掉
kill 18

[*]然后再启动即可
热更新

Watcher 组件除了办理上述启动问题,还提供了文件修改后立马重启的功能。
安装

composer require hyperf/watcher --dev
发布配置

php bin/hyperf.php vendor:publish hyperf/watcher
   发布配置后在目录config/autoload/下自动生成watcher.php文件
https://i-blog.csdnimg.cn/direct/a7eb3db84f0c4172a65f31f1af12e9cf.png
配置 默认值 备注
driverScanFileDriver默认定时扫描文件驱动binPHP_BINARY用于启动服务的脚本watch.dirapp, config监听目录watch.file.env监听文件watch.interval2000扫描隔断(毫秒)ext.php, .env监听目录下的文件扩展名 启动

hyperf框架可以利用hyperf/watcher举行热更新操纵,不消每次修改完代码都重启服务
注意:
利用php bin/hyperf.php server:watch
这个命令后,php bin/hyperf.php start 这个命令将废弃
php bin/hyperf.php server:watch
路由

配置文件路由

<?php
use Hyperf\HttpServer\Router\Router;

// 此处代码示例为每个示例都提供了三种不同的绑定定义方式,实际配置时仅可采用一种且仅定义一次相同的路由

// 设置一个 GET 请求的路由,绑定访问地址 '/get' 到 App\Controller\IndexController 的 get 方法
Router::get('/get', 'App\Controller\IndexController::get');
Router::get('/get', 'App\Controller\IndexController@get');
Router::get('/get', [\App\Controller\IndexController::class, 'get']);

// 设置一个 POST 请求的路由,绑定访问地址 '/post' 到 App\Controller\IndexController 的 post 方法
Router::post('/post', 'App\Controller\IndexController::post');
Router::post('/post', 'App\Controller\IndexController@post');
Router::post('/post', [\App\Controller\IndexController::class, 'post']);

// 设置一个允许 GET、POST 和 HEAD 请求的路由,绑定访问地址 '/multi' 到 App\Controller\IndexController 的 multi 方法
Router::addRoute(['GET', 'POST', 'HEAD'], '/multi', 'App\Controller\IndexController::multi');
Router::addRoute(['GET', 'POST', 'HEAD'], '/multi', 'App\Controller\IndexController@multi');
Router::addRoute(['GET', 'POST', 'HEAD'], '/multi', [\App\Controller\IndexController::class, 'multi']);
路由组

Router::addGroup('/user',function (){
    Router::get('/index', 'App\Controller\UserController::index');
    Router::post('/create', 'App\Controller\UserController::createUser');
    Router::put('/update', 'App\Controller\UserController::update');
    Router::delete('/delete', 'App\Controller\UserController::delete');
});

必填参数

我们可以对 $uri 举行一些参数界说,通过 {} 来声明参数,如 /user/{id} 则声明了 id 值为一个必填参数。
可选参数

偶然间您大概会希望这个参数是可选的,您可以通过[]来声明中括号内的参数为一个可选参数,如 /user/[{id}]。
校验参数

您也可以利用正则表达式对参数举行校验,以下是一些例子
use Hyperf\HttpServer\Router\Router;

// 可以匹配 /user/42, 但不能匹配 /user/xyz
Router::addRoute('GET', '/user/{id:\d+}', 'handler');

// 可以匹配 /user/foobar, 但不能匹配 /user/foo/bar
Router::addRoute('GET', '/user/{name}', 'handler');

// 也可以匹配 /user/foo/bar as well
Router::addRoute('GET', '/user/{name:.+}', 'handler');

// 这个路由
Router::addRoute('GET', '/user/{id:\d+}[/{name}]', 'handler');
// 等同于以下的两个路由
Router::addRoute('GET', '/user/{id:\d+}', 'handler');
Router::addRoute('GET', '/user/{id:\d+}/{name}', 'handler');

// 多个可选的嵌套也是允许的
Router::addRoute('GET', '/user[/{id:\d+}[/{name}]]', 'handler');

// 这是一条无效的路由, 因为可选部分只能出现在最后
Router::addRoute('GET', '/user[/{id:\d+}]/{name}', 'handler');
注解路由

https://i-blog.csdnimg.cn/direct/0f6c95e78e6f40158f9acde9308af55e.png
例如:
<?php
/**
* OrderController.php
*
* Created on Orders-11:19
* Created by xxp 332410549@qq.com
*/

namespace App\Controller;


use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Contract\RequestInterface;


/**
* @Controller(prefix="order")
*/
class OrderController extends AbstractController
{

    /**
   * @GetMapping(path="index")
   */
    public function index(RequestInterface $request)
    {
      return 'OrderController'.$request->input('id');
    }
}
访问地点
http://hyperf.demos.xp:9501/order/index
HTTP 非常

在路由匹配不到路由时,如 路由找不到(404)、请求方法不答应(405) 等 HTTP 非常,Hyperf 会同一抛出一个 Hyperf\HttpMessage\Exception\HttpException 非常类的子类,
您需要通过 ExceptionHandler 机制来管理这些非常并做对应的响应处理,默认环境下可以直接利用组件提供的 Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler 来举行非常捕获处理,注意这个非常处理器需要您自行配置到 config/autoload/exceptions.php 配置文件中去,并保障多个非常处理器之间的序次链路是正确的。
当您需要对 路由找不到(404)、请求方法不答应(405) 等 HTTP 非常环境的响应举行自界说处理时,您可直接根据 HttpExceptionHandler 的代码实现您自己的非常处理器,并配置您自己的非常处理器。关于非常处理器的逻辑和利用说明,可具体查阅 非常处理
非常处理器

在 Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦恣意一个请求的业务存在没有捕获处理的非常的话,都会导致对应的 Worker 进程 被停止退出,这对服务而言也是不能接受的,捕获非常并输出公道的报错内容给客户端也是更加友好的。
我们可以通过对各个 server 界说不同的 非常处理器(ExceptionHandler),一旦业务流程存在没有捕获的非常,都会被通报到已注册的 非常处理器(ExceptionHandler) 去处理。
自界说一个非常处理

https://i-blog.csdnimg.cn/direct/74a1608df0734922902ba0ae2f99bf66.png
1. 通过配置文件注册非常处理器

config/autoload/exceptions.php 文件
<?php
// config/autoload/exceptions.php
return [
    'handler' => [
      'http' => [
            Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
            App\Exception\Handler\AppExceptionHandler::class,
            App\Exception\Handler\FooExceptionHandler::class,
      ],
    ],
];


2. 界说非常处理器

app/Exception/Handler/FooExceptionHandler.php
<?php
/**
* FooExceptionHandler.php
*
* Created on ExceptionHandler -13:35
* Created by xxp 332410549@qq.com
*/

namespace App\Exception\Handler;

use App\Exception\FooException;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;

class FooExceptionHandler extends ExceptionHandler
{

    /**
   * @inheritDoc
   */
    public function handle(Throwable $throwable, ResponseInterface $response)
    {
      // 判断被捕获到的异常是希望被捕获的异常
      if ($throwable instanceof FooException) {
            // 格式化输出
            $data = json_encode([
                'code' => $throwable->getCode(),
                'message' => $throwable->getMessage(),
            ], JSON_UNESCAPED_UNICODE);

            // 阻止异常冒泡
            $this->stopPropagation();
            return $response->withStatus(500)->withBody(new SwooleStream($data));
      }

      // 交给下一个异常处理器
      return $response;
    }

    /**
   * @inheritDoc
   */
    public function isValid(Throwable $throwable): bool
    {
       return true;
    }

}
3. 界说非常类

app/Exception/FooException.php
<?php
/**
* FooException.php
*
* Created on FooException-13:40
* Created by xxp 332410549@qq.com
*/

namespace App\Exception;

use Hyperf\Server\Exception\ServerException;

class FooException extends ServerException
{


}
4. 触发非常

<?php
/**
* OrderController.php
*
* Created on Orders-11:19
* Created by xxp 332410549@qq.com
*/

namespace App\Controller;


use App\Exception\FooException;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Contract\RequestInterface;


/**
* @Controller(prefix="order")
*/
class OrderController extends AbstractController
{

    /**
   * @GetMapping(path="index")
   */
    public function index(RequestInterface $request)
    {
      try {

            $data = [
                'code' => 0,
                'msg' => '获取成功',
                'data' => [
                  'orders' => '订单列表'
                ]
            ];
            if (1) {   // 如果没有数据,返回空数组
            throw new FooException('自定义异常');
            }
            return $this->response->json($data);
      } catch (\Exception $e) {
            return $this->response->json(['code' => 1,'msg' => $e->getMessage()]);
      }
    }



}
检察办理

https://i-blog.csdnimg.cn/direct/0bf3b96071f04fe697aed984c8ca63f9.png
总结:
在上面这个例子,我们先假设 FooException 是存在的一个非常,以及假设已经完成了该处理器的配置,那么当业务抛出一个没有被捕获处理的非常时,就会根据配置的序次依次通报,整一个处理流程可以明白为一个管道,若前一个非常处理器调用 $this->stopPropagation() 则不再往后通报,若最后一个配置的非常处理器仍不对该非常举行捕获处理,那么就会交由 Hyperf 的默认非常处理器处理了。
Error 监听器

框架提供了 error_reporting() 错误级别的监听器 Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler。
配置

在 config/autoload/listeners.php 中添加监听器
<?php
return [
    \Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler::class
];
抓取错误

则当出现类似以下的代码时会抛出 \ErrorException 非常
    public function index(RequestInterface $request)
    {
      try {

            $a = [];
            ($a);
            return $this->response->json($data);
      } catch (\Throwable $e) {
            return $this->response->json(['code' => 1,'msg' => $e->getMessage() ."\n num:". $e->getLine()]);
      }
    }
结果

https://i-blog.csdnimg.cn/direct/2ce60da2a68d4ce888502d9775237eef.png
中间件

原理图

中间件重要用于编织从 请求(Request) 到 响应(Response) 的整个流程,通过对多个中间件的组织,使数据的流动按我们预定的方式举行,中间件的本质是一个 洋葱模型
https://i-blog.csdnimg.cn/direct/69f3f3420c8e4578ae0705372aec54d8.png
图中的序次为按照 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 ,配置如下:
<?php
return [
    // http 对应 config/autoload/server.php 内每个 server 的 name 属性对应的值,该配置仅应用在该 Server 中
    'http' => [
      // 数组内配置您的全局中间件,顺序根据该数组的顺序
      YourMiddleware::class
    ],
];
只需将您的全局中间件配置在该文件及对应的 Server Name 内,即该 Server 下的所有请求都会应用配置的全局中间件。
界说局部中间件

当我们有些中间件仅仅面向某些请求或控制器时,即可将其界说为局部中间件,可通过配置文件的方式界说或注解的方式。
通过配置文件界说

在利用配置文件界说路由时,您仅可通过配置文件来界说对应的中间件,局部中间件的配置将在路由配置上完成。
Hyperf\HttpServer\Router\Router 类的每个界说路由的方法的最后一个参数 $options 都将接收一个数组,可通过通报键值 middleware 及一个数组值来界说该路由的中间件,我们通过几个路由界说来演示一下:
<?php
use App\Middleware\FooMiddleware;
use Hyperf\HttpServer\Router\Router;

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

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

在通过注解界说路由时,您仅可通过注解的方式来界说中间件,对中间件的界说有两个注解,分别为:
# 注解为界说单个中间件时利用,在一个地方仅可界说一个该注解,不可重复界说
# 注解为界说多个中间件时利用,在一个地方仅可界说一个该注解,然后通过在该注解内界说多个 # 注解实现多个中间件的界说
利用 # 注解时需 use Hyperf\HttpServer\Annotation\Middleware; 命名空间;
利用 # 注解时需 use Hyperf\HttpServer\Annotation\Middlewares; 命名空间;
注意:必须共同 # 大概 # 利用
界说单个中间件:

<?php
namespace App\Controller;

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

#
#
class IndexController
{
    public function index()
    {
      return 'Hello Hyperf.';
    }
}
通过 # 注解界说多个中间件:

<?php
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;

#
#)]
class IndexController
{
    public function index()
    {
      return 'Hello Hyperf.';
    }
}
界说方法级别的中间件

在通过配置文件的方式配置中间件时界说到方法级别上很简朴,那么要通过注解的情势界说到方法级别呢?您只需将注解直接界说到方法上即可。
类级别上的中间件会优先于方法级别的中间件,我们通过代码来举例一下:
<?php
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;

#
#)]
class IndexController
{
    #
    public function index()
    {
      return 'Hello Hyperf.';
    }
}
中间件相干的代码
生成中间件
php ./bin/hyperf.php gen:middleware Auth/FooMiddleware
<?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
{
    protected ContainerInterface $container;

    protected RequestInterface $request;

    protected HttpResponse $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无效,阻止继续向下执行',
                ],
            ]
      );
    }
}
中间件的执行序次为 FooMiddleware -> BarMiddleware。
中间件的执行序次

我们从上面可以相识到总共有 3 种级别的中间件,分别为 全局中间件、类级别中间件、方法级别中间件,假如都界说了这些中间件,执行序次为:全局中间件 -> 类级别中间件 -> 方法级别中间件。
在>=3.0.34的版本中,新增了优先级的配置,可以在配置方法、路由中间件的时间改变中间件的执行序次,优先级越高,执行序次越靠前。
// 全局中间件配置文件 middleware.php
return [
    'http' => [
      YourMiddleware::class,
      YourMiddlewareB::class => 3,
    ],
];
Copy to clipboardErrorCopied
// 路由中间件配置
Router::addGroup(
    '/v2', function () {
      Router::get('/index', [\App\Controller\IndexController::class, 'index']);
    },
    [
      'middleware' => [
            FooMiddleware::class,
            FooMiddlewareB::class => 3,
      ]
    ]
);
// 注解中间件配置
#
#
#
#)]
class IndexController
{
   
}
全局更改请求和响应对象

首先,在协程上下文内是有存储最原始的 PSR-7 请求对象 和 响应对象 的,且根据 PSR-7 对相干对象所要求的 不可变性(immutable),也就意味着我们在调用 $response = $response->with***() 所调用得到的 $response,并非为改写原对象,而是一个 Clone 出来的新对象,也就意味着我们储存在协程上下文内的 请求对象 和 响应对象 是不会改变的,那么当我们在中间件内的某些逻辑改变了 请求对象 或 响应对象,而且我们希望对后续的 非通报性的 代码再获取改变后的 请求对象 或 响应对象,那么我们便可以在改变对象后,将新的对象设置到上下文中,如代码所示:
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

// $request 和 $response 为修改后的对象
$request = \Hyperf\Context\Context::set(ServerRequestInterface::class, $request);
$response = \Hyperf\Context\Context::set(ResponseInterface::class, $response);
自界说 CoreMiddleWare 的举动

默认环境下,Hyperf 在处理路由找不到或 HTTP 方法不答应时,即 HTTP 状态码为 404、405 的时间,是由 CoreMiddleware 直接处理并返回对应的响应对象的,得益于 Hyperf 依靠注入的设计,您可以通过更换对象的方式来把 CoreMiddleware 指向由您自己实现的 CoreMiddleware 去。
比如我们希望界说一个 App\Middleware\CoreMiddleware 类来重写默认的举动,我们可以先界说一个 App\Middleware\CoreMiddleware 类如下,这里我们仅以 HTTP Server 为例,其它 Server 也可采用同样的做法来达到同样的目的。
<?php
declare(strict_types=1);

namespace App\Middleware;

use Hyperf\Contract\Arrayable;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class CoreMiddleware extends \Hyperf\HttpServer\CoreMiddleware
{
    /**
   * Handle the response when cannot found any routes.
   *
   * @return array|Arrayable|mixed|ResponseInterface|string
   */
    protected function handleNotFound(ServerRequestInterface $request)
    {
      // 重写路由找不到的处理逻辑
      return $this->response()->withStatus(404);
    }

    /**
   * Handle the response when the routes found but doesn't match any available methods.
   *
   * @return array|Arrayable|mixed|ResponseInterface|string
   */
    protected function handleMethodNotAllowed(array $methods, ServerRequestInterface $request)
    {
      // 重写 HTTP 方法不允许的处理逻辑
      return $this->response()->withStatus(405);
    }
}
然后再在 config/autoload/dependencies.php 界说对象关系重写 CoreMiddleware 对象:
<?php
return [
    Hyperf\HttpServer\CoreMiddleware::class => App\Middleware\CoreMiddleware::class,
];
这里直接重写 CoreMiddleware 的做法需要在 1.1.0+ 版本上才有效,1.0.x 版本仍需要你再将 CoreMiddleware 的上层调用通过 DI 举行重写,然后更换 CoreMiddleware 的传值为您界说的中间件类。
常用中间件

跨域中间件
假如您需要在框架中办理跨域,则可以按照您的需求实现以下中间件
<?php

declare(strict_types=1);

namespace App\Middleware;

use Hyperf\Context\Context;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class CorsMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
      $response = Context::get(ResponseInterface::class);
      $response = $response->withHeader('Access-Control-Allow-Origin', '*')
            ->withHeader('Access-Control-Allow-Credentials', 'true')
            // Headers 可以根据实际情况进行改写。
            ->withHeader('Access-Control-Allow-Headers', 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,Authorization');

      Context::set(ResponseInterface::class, $response);

      if ($request->getMethod() == 'OPTIONS') {
            return $response;
      }

      return $handler->handle($request);
    }
}
实际上,跨域配置也可以直接挂在 Nginx 上。
location / {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,Authorization';

    if ($request_method = 'OPTIONS') {
      return 204;
    }
}
后置中间件
通常环境下,我们都是最后执行
return                                    h                         a                         n                         d                         l                         e                         r                         −                         >                         h                         a                         n                         d                         l                         e                         (                              handler->handle(                  handler−>handle(request);
Copy to clipboardErrorCopied
所以,相称于是前置中间件,假如想要让中间件逻辑后置,其实只需要更换一下执行序次即可。
<?php

declare(strict_types=1);

namespace App\Middleware;

use Hyperf\HttpServer\Contract\RequestInterface;
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 OpenApiMiddleware implements MiddlewareInterface
{
    public function __construct(protected ContainerInterface $container)
    {
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
      // TODO: 前置操作
      try{
            $result = $handler->handle($request);
      } finally {
            // TODO: 后置操作
      }
      return $result;
    }
}
实践

https://i-blog.csdnimg.cn/direct/24f24c50e4504fdc82d2270d54f8e185.png
中间件文件

<?php

declare(strict_types=1);

namespace App\Middleware\Auth;

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

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
    {
      $isValidToken = true;
      if ($isValidToken) {
            return $handler->handle($request);
      }

      return $this->response->json(
            [
                'code' => -1,
                'data' => [
                  'error' => '中间件验证token无效,阻止继续向下执行 ',
                ],
            ]
      );
    }
}
$isValidToken 根据具体业务来判断
假如为真,则放行
假如为假,则阻断
中间件调用

<?php
/**
* Message.php
*
* Created on Message-15:28
* Created by xxp 332410549@qq.com
*/

namespace App\Controller;

use Hyperf\HttpServer\Annotation\AutoController;
use App\Controller\AbstractController;
use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\Auth\FooMiddleware;
/**
* @AutoController()
* @Middleware(FooMiddleware::class)
*/
class MessageController extends AbstractController
{

    public function index()
    {
      return 'message';
    }
}
结果

https://i-blog.csdnimg.cn/direct/4f8d709846784c4fb33a6dc532c6b068.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Hyperf 安装,利用,