Hyperf框架 - 事件机制

事件机制包含三个角色。

事件Event

定义一个类,一般需要存储一些源数据,因此事件对象应该采用短生命周期的写法,即使用 new UserRegisterd($userId) 的写法。

调度器Dispatcher

触发事件,一般需要传递源数据到事件对象里,并且使该事件的所有监听者去做相应的处理。

监听器Listenner

调度器会将事件对象传递到监听器,监听器得到事件并做相应的处理。由于对象的传递是引用传递,且监听器是串行执行的,所以在监听器里面可以改变事件对象的数据,以传递到下一个监听器继续处理,一个事件可以被多个监听器监听,一个监听器可以监听多个事件,可以设置监听器的执行先后顺序。

定义两个事件

app/Event/UserPayedEvent.php

<?php

namespace App\Event;


class UserPayedEvent
{
    public $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function __destruct()
    {
        echo 'UserPayedEvent destruct'.PHP_EOL;
    }
}

app/Event/UserRegisterEvent.php

<?php

namespace App\Event;


class UserRegisterEvent
{
    public $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function __destruct()
    {
        echo 'UserRegisterEvent destruct'.PHP_EOL;
    }
}
定义两个监听器

app/Listener/SendEmailListener.php

<?php

namespace App\Listener;


use App\Event\UserRegisterEvent;
use Hyperf\Event\Contract\ListenerInterface;

class SendEmailListener implements ListenerInterface
{

    public function listen(): array
    {
        return [
            UserRegisterEvent::class
        ];
    }

    public function process(object $event)
    {
        echo 'SendEmailListener done' . PHP_EOL;
        var_dump($event->data);
    }
}

app/Listener/SendSmsListener.php

<?php

namespace App\Listener;


use App\Event\UserPayedEvent;
use App\Event\UserRegisterEvent;
use Hyperf\Event\Contract\ListenerInterface;
use Swoole\Coroutine\System;

class SendSmsListener implements ListenerInterface
{

    public function listen(): array
    {
        return [
            UserRegisterEvent::class,
            UserPayedEvent::class,
        ];
    }

    public function process(object $event)
    {
        System::sleep(3);
        echo 'SendSmsListener done' . PHP_EOL;
        var_dump($event->data);
    }
}
注册监听器到配置文件

排在前面的监听器先被执行。

config/autoload/listeners.php

<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
return [
    \App\Listener\SendSmsListener::class,
    \App\Listener\SendEmailListener::class,
];
投递事件

app/Controller/IndexController.php

<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace App\Controller;

use App\Event\UserPayedEvent;
use App\Event\UserRegisterEvent;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\AutoController;
use Psr\EventDispatcher\EventDispatcherInterface;

/**
 * @AutoController()
 */
class IndexController extends AbstractController
{
    /**
     * @Inject()
     * @var EventDispatcherInterface
     */
    protected $eventDispatcher;

    public function testUserRegister()
    {
        $userId = $this->request->input('userId', 0);
        $this->eventDispatcher->dispatch((new UserRegisterEvent($userId)));
        echo 'done'.PHP_EOL;
    }

    public function testUserPayed()
    {
        $userId = $this->request->input('userId', 0);
        $money = $this->request->input('money', 0);
        $this->eventDispatcher->dispatch((new UserPayedEvent(['userId'=>$userId, 'money'=>$money])));
    }
}

多个监听器是串行的,且是有顺序的。
事件对象被最后一个监听器执行完就会被释放掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值