事件机制

    事件模式是一种经过了充分测试的可靠机制,是一种非常适用于解耦的机制,分别存在以下 3 种角色:

    • 是传递于应用代码与 监听器(Listener) 之间的通讯对象
    • 监听器(Listener) 是用于监听 事件(Event) 的发生的监听对象
    • 事件调度器(EventDispatcher) 是用于触发 事件(Event) 和管理 监听器(Listener)事件(Event) 之间的关系的管理者对象 用通俗易懂的例子来说明就是,假设我们存在一个 UserService::register() 方法用于注册一个账号,在账号注册成功后我们可以通过事件调度器触发 UserRegistered 事件,由监听器监听该事件的发生,在触发时进行某些操作,比如发送用户注册成功短信,在业务发展的同时我们可能会希望在用户注册成功之后做更多的事情,比如发送用户注册成功的邮件等待,此时我们就可以通过再增加一个监听器监听 UserRegistered 事件即可,无需在 UserService::register() 方法内部增加与之无关的代码。

    一个事件其实就是一个用于管理状态数据的普通类,触发时将应用数据传递到事件里,然后监听器对事件类进行操作,一个事件可被多个监听器监听。

    1. <?php
    2. namespace App\Event;
    3. class UserRegistered
    4. {
    5. public function __construct($user)
    6. {
    7. $this->user = $user;
    8. }

    通过配置文件注册监听器

    在定义完监听器之后,我们需要让其能被 事件调度器(Dispatcher) 发现,可以在 config/autoload/listeners.php 配置文件 (如不存在可自行创建) 内添加该监听器即可,监听器的触发顺序根据该配置文件的配置顺序:

    1. <?php
    2. return [
    3. \App\Listener\UserRegisteredListener::class,
    4. ];

    Hyperf 还提供了一种更加简便的监听器注册方式,就是通过 @Listener 注解注册,只要将该注解定义在监听器类上,且监听器类处于 Hyperf 注解扫描域 内即可自动完成注册,代码示例如下:

    事件需要通过 事件调度器(EventDispatcher) 调度才能让 监听器(Listener) 监听到,我们通过一段代码来演示如何触发事件:

    1. <?php
    2. namespace App\Service;
    3. use Psr\EventDispatcher\EventDispatcherInterface;
    4. {
    5. /**
    6. * @Inject
    7. * @var EventDispatcherInterface
    8. */
    9. private $eventDispatcher;
    10. public function register()
    11. {
    12. // 我们假设存在 User 这个实体
    13. $user = new User();
    14. $result = $user->save();
    15. // 完成账号注册的逻辑
    16. // 这里 dispatch(object $event) 会逐个运行监听该事件的监听器
    17. $this->eventDispatcher->dispatch(new UserRegistered($user));
    18. return $result;
    19. }