事件管理

在swoft我们将事件分为三大类:

  • swoole server的回调事件
  • swoft server的事件,基于swoole的回调处理,扩展了一些可用事件以增强自定义性
  • 应用内的自定义事件管理和使用。也是我们通常了解和使用的事件管理了。

swoole和server级别的事件监听器,应当放置在boot阶段。(即通常应放置于 App\Boot 空间下)

Swoole Server 事件

用注解tag @SwooleListener("event name") 来注册swoole的回调事件监听, 支持所有swoole官网列出来的事件回调名。
具体请查看 SwooleEvent::class 以及 swoole官网。

请谨慎使用 @SwooleListener。 它是直接注册到 swoole server上的(监听相同事件将会被覆盖),操作不当可能导致出现问题。

Swoft Server 事件

用注解tag @ServerListener("event name") 来注册服务器级别的事件监听。

它是对 @SwooleListener 的补充扩展,除了支持swoole的事件以外,还增加了一些额外的可用事件监听。

两者的区别是:

  • SwooleListener 中一个事件的监听器只允许一个,并且是直接注册到 swoole server上的(监听相同事件将会被覆盖)
  • ServerListener 允许对swoole事件添加多个监听器,会逐个通知
  • ServerListener 不影响基础swoole事件的监听

Examples:

  1. <?php
  2. namespace App\Boot\Listener;
  3. use Swoft\Bean\Annotation\ServerListener;
  4. use Swoft\Bootstrap\Listeners\Interfaces\StartInterface;
  5. use Swoft\Bootstrap\SwooleEvent;
  6. use Swoole\Server;
  7. /**
  8. * Class TestStartListener
  9. * @package App\Boot\Listener
  10. * @ServerListener(event=SwooleEvent::ON_START)
  11. */
  12. class MyServerListener implements StartInterface
  13. {
  14. /**
  15. * @var Server $server
  16. * */
  17. public function onStart(Server $server)
  18. {
  19. \output()->writeln('TestStartListener');
  20. var_dump('TestStartListener');
  21. }
  22. }

自定义事件

基本的事件注册与触发管理

  • implement the Psr 14 - Event dispatcher
  • 支持设置事件优先级
  • 支持快速的事件组注册
  • 支持通配符事件的监听

作为核心服务组件,事件管理会自动启用

  1. 'eventManager' => [
  2. 'class' => \Swoft\Event\EventManager::class,
  3. ],

注册事件监听

  • 用注解tag @Listener("event name") 来注册用户自定义的事件监听
  1. /**
  2. * 应用加载事件
  3. *
  4. * @Listener(AppEvent::APPLICATION_LOADER)
  5. */
  6. class ApplicationLoaderListener implements EventHandlerInterface
  7. {
  8. /**
  9. * @param EventInterface $event 事件对象
  10. */
  11. public function handle(EventInterface $event)
  12. {
  13. // do something ....
  14. }
  15. }

事件名称管理推荐放置在一个单独类的常量里面,方便管理和维护

  • 触发事件
  1. \Swoft::trigger('event name', null, $arg0, $arg1);
  2. // OR use \Swoft\App::trigger();

拓展介绍

一些关于自定义事件的拓展介绍说明

事件分组

除了一些特殊的事件外,在一个应用中,大多数事件是有关联的,此时我们就可以对事件进行分组,方便识别和管理使用。

  • 事件分组 推荐将相关的事件,在名称设计上进行分组

例如:

  1. // 模型相关:
  2. model.insert
  3. model.update
  4. model.delete
  5. // DB相关:
  6. db.connect
  7. db.disconnect
  8. db.query
  9. // 应用相关:
  10. app.start
  11. app.run
  12. app.stop

事件通配符 *

支持使用事件通配符 * 对一组相关的事件进行监听, 分两种。

  1. * 全局的事件通配符。直接对 * 添加监听器($em->attach('*', 'global_listener')), 此时所有触发的事件都会被此监听器接收到。
  2. {prefix}.* 指定分组事件的监听。eg $em->attach('db.*', 'db_listener'), 此时所有触发的以 db. 为前缀的事件(eg db.query db.connect)都会被此监听器接收到。

当然,你在事件到达监听器前停止了本次事件的传播$event->stopPropagation(true);,就不会被后面的监听器接收到了。

更多介绍

更多关于自定义事件的理解参考 https://github.com/inhere/php-event-manager/blob/master/README.md