美文网首页
转载 Hyperf 3 快速使用 - 事件机制的使用

转载 Hyperf 3 快速使用 - 事件机制的使用

作者: geeooooz | 来源:发表于2023-06-13 14:35 被阅读0次

    原出处:https://www.ziruchu.com/art/619

    事件模型必须基于 PSR-14 规范实现。

    事件概念

    事件模式是一种经过了充分测试的可靠机制,是一种非常适用于解耦的机制,分别存在以下 3 种角色:
    
    事件(Event) 是传递于应用代码与 监听器(Listener) 之间的通讯对象
    
    监听器(Listener) 是用于监听 事件(Event) 的发生的监听对象
    
    事件调度器(EventDispatcher) 是用于触发 事件(Event) 和管理 监听器(Listener) 与 事件(Event) 之间的关系的管理者对象
    
    举例来说,比如用户注册之后,我们要发送一封邮件给用户。可以使用事件与监听者来实现:
    
    1)定义一个用户注册事件;
    
    2)定义一个监听事件的监听者;
    
    3)事件调度器调度事件(也就是开始使用事件了);
    
    4)事件一旦被触发,监听者就会监听到,从而相应的逻辑处理。
    

    使用事件
    方式一:基础使用
    第一步:定义一个事件

    <?php
    //  App\Event\UserRegistered.php
    namespace App\Event;
    
    // 用户注册事件
    use App\Model\User;
    
    class UserRegistered
    {
       public function __construct(public User $user)
       {
       }
    }
    

    第二步:定义一个监听者

    监听器都需要实现一下 Hyperf\Event\Contract\ListenerInterface 接口的约束方法。

    <?php
    // App\Listener\UserRegisteredListener.php
    
    namespace App\Listener;
    
    use App\Event\UserRegistered;
    use Hyperf\Event\Contract\ListenerInterface;
    
    class UserRegisteredListener implements ListenerInterface
    {
       public function listen(): array
       {
           // 该监听器需要监听的事件,可以监听多个事件
           return [
               UserRegistered::class
           ];
       }
    
       public function process(object $event): void
       {
           // 此处是事件触发后的业务逻辑处理
           echo '用户注册事件触发,我执行了, 用户 ID:' . $event->user->id;
       }
    }
    

    第三步:注册监听器

    <?php
    // config/autoload/listeners.php
    declare(strict_types=1);
    
    return [
       \App\Listener\UserRegisteredListener::class,
    ];
    

    第四步:事件调度器分发事件

    此处我在控制器进行事件调度。可以在其他位置进行事件调度,如 UserService 层。

    <?php
    // App\Controller\Test\UserController.php
    
    use Psr\EventDispatcher\EventDispatcherInterface;
    
    #[Inject]
    protected EventDispatcherInterface $dispatcher;
    
    #[GetMapping('/users/store')]
    public function store()
    {
       $user = User::query()->find(1);
    
       // 事件调度
       $this->dispatcher->dispatch(new UserRegistered($user));
    }
    

    方式二:注解方式使用事件
    Hyperf 提供了更为方便的监听器注册方式,使用 #[Listener] 进行注解后,就不需要在配置文件 listeners.php 中注册了。使用方式如下:

    <?php
    // App\Listener\UserRegisteredListener.php
       
    namespace App\Listener;
    
    use App\Event\UserRegistered;
    use Hyperf\Event\Annotation\Listener;
    use Hyperf\Event\Contract\ListenerInterface;
    
    // 注册方式注册监听者
    #[Listener]
    class UserRegisteredListener implements ListenerInterface
    {
    // 代码省略
    }
    

    当使用注解注册监听器时,可以通过设置 priority 属性定义当前监听器的,如 #[Listener(priority=1)],底层使用 SplPriorityQueue 结构储存,priority 数字越大优先级越高。

    使用 #[Listener] 注解时需 use Hyperf\Event\Annotation\Listener; 命名空间;

    对于事件,理解加实操更容器理解。

    测试demo:

    <?php
    
    
    namespace App\Event;
    // 用户注册事件
    use App\Model\User;
    
    class UserRegistered
    {
        public function __construct(public User $user)
        {
    
        }
    }
    
    <?php
    // App\Listener\UserRegisteredListener.php
    
    namespace App\Listener;
    
    use App\Event\UserRegistered;
    use Hyperf\Event\Annotation\Listener;
    use Hyperf\Event\Contract\ListenerInterface;
    // 注册方式注册监听者
    #[Listener]
    class UserRegisteredListener implements ListenerInterface
    {
        public function listen(): array
        {
            // 该监听器需要监听的事件,可以监听多个事件
            return [
                UserRegistered::class
            ];
        }
    
        public function process(object $event): void
        {
            var_dump($event);
            // 此处是事件触发后的业务逻辑处理
            echo '用户注册事件触发,我执行了, 用户 ID:' . $event->user->id;
        }
    }
    
    <?php
    
    declare(strict_types=1);
    /**
     * This file is part of Hyperf.
     *
     * @link     https://www.hyperf.io
     * @document https://hyperf.wiki
     * @contact  group@hyperf.io
     * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
     */
    namespace App\Controller;
    
    use App\Event\UserRegistered;
    use App\Model\OrderTest;
    use App\Model\User;
    use App\Service\UserService;
    use Hyperf\Di\Annotation\Inject;
    use Hyperf\HttpServer\Annotation\Controller;
    use Hyperf\HttpServer\Annotation\GetMapping;
    use Psr\EventDispatcher\EventDispatcherInterface;
    
    #[Controller(prefix: "lgbhf/index")]
    
    class IndexController extends AbstractController
    {
    
    
        #[Inject]
        protected EventDispatcherInterface $dispatcher;
    
        #[GetMapping('store')]
        public function store()
        {
            $user = User::query()->find(1);
            // 事件调度
            $this->dispatcher->dispatch(new UserRegistered($user));
        }
    }
    

    相关文章

      网友评论

          本文标题:转载 Hyperf 3 快速使用 - 事件机制的使用

          本文链接:https://www.haomeiwen.com/subject/gnpcydtx.html