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

2023-06-13  本文已影响0人  geeooooz

原出处: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));
    }
}
上一篇 下一篇

猜你喜欢

热点阅读