10、Hyperf 3 快速使用 - 事件机制的使用

作者: 温新

分类: 【Hyperf 3 基础系列】

阅读: 415

时间: 2023-04-25 12:23:32

hi,我是温新,一名 PHPer

Hypref 版本:Hyperf 3.0

学习目标:学习使用事件

事件模型必须基于 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; 命名空间;

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

请登录后再评论