jmikola/ wildcard-event-dispatcher
受AMQP主题交换启发的支持通配符模式的事件派发器。
Requires
- php: ^7.2 || ^8.0
- symfony/event-dispatcher: ^4.3 || ^5.0
Requires (Dev)
- phpunit/phpunit: ^8.0
README
此库实现了一个基于Symfony接口的事件派发器,受AMQP主题交换的通配符语法启发。监听器可以绑定到通配符模式,并在派发的事件名称与该模式匹配时被通知。仍然支持字面事件名称匹配。
注意:此库使用的通配符语法与在Symfony 4.3中引入的简化事件派发不兼容,该语法使用事件的全限定名称(FQCN)而不是自定义字符串(例如 core.request
)。
如果您有兴趣在Symfony项目中使用此库,您还可以查看相应的扩展包。
安装
$ composer require jmikola/wildcard-event-dispatcher=^2.0
兼容性
此库需要Symfony 4.3或更高版本。
使用
WildcardEventDispatcher实现了EventDispatcherInterface,可以像使用Symfony的标准EventDispatcher一样使用。
<?php use Jmikola\WildcardEventDispatcher\WildcardEventDispatcher; use Symfony\Component\EventDispatcher\Event; $dispatcher = new WildcardEventDispatcher(); $dispatcher->addListener('core.*', function(Event $e) { echo $e->getName(); }); $dispatcher->dispatch('core.request'); // "core.request" will be printed
内部,WildcardEventDispatcher实际上组合了一个EventDispatcherInterface实例,它依赖于该实例进行事件处理。默认情况下,WildcardEventDispatcher将为内部使用构造一个EventDispatcher对象,但您可以在构造函数中指定要包装的特定的EventDispatcherInterface实例。
<?php use Jmikola\WildcardEventDispatcher\WildcardEventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new WildcardEventDispatcher(new EventDispatcher());
通配符语法
单词通配符
考虑这样一个场景,同一个监听器被定义用于多个事件,所有这些事件都有一个共同的词根。
<?php $coreListener = function(Event $e) {}; $dispatcher = new WildcardEventDispatcher(); $dispatcher->addListener('core.exception', $coreListener); $dispatcher->addListener('core.request', $coreListener); $dispatcher->addListener('core.response', $coreListener);
这些事件名称都由两个点分隔的词组成。这个“词”的概念对于理解通配符模式的应用非常重要。
在这个例子中,监听器负责观察应用程序中的所有core
事件。假设它需要将这些事件的某些详细信息记录到外部服务器。我们可以通过使用单词通配符*
来重构多个addListener()
调用。
<?php $coreListener = function(Event $e) {}; $dispatcher = new WildcardEventDispatcher(); $dispatcher->addListener('core.*', $coreListener);
现在,监听器将观察所有名为core
或以core.
开头并跟另一个词的事件。单独匹配core
可能没有意义,但这是为了与AMQP保持一致。一个非空序列后面的*
可以匹配前面的序列,但不包括.*
。
多词通配符
假设您的应用程序中有一个名为core.foo.bar
的core
事件。上述core.*
模式将无法捕获此事件。您可以使用以下语法:
<?php $coreListener = function(Event $e) {}; $dispatcher = new WildcardEventDispatcher(); $dispatcher->addListener('core.*.*', $coreListener);
此语法将匹配core.foo
和core.foo.bar
,但core
将不再匹配(假设存在此类事件)。
在这里,多词通配符#
可能更合适。
<?php $coreListener = function(Event $e) {}; $dispatcher = new WildcardEventDispatcher(); $dispatcher->addListener('core.#', $coreListener);
假设应用程序中还有一个监听器需要监听应用程序中的所有事件。多词通配符#
可以被使用:
<?php $allListener = function(Event $e) {}; $dispatcher = new WildcardEventDispatcher(); $dispatcher->addListener('#', $allListener);
附加通配符文档
如有疑问,ListenerPattern
的单元测试是一个很好的资源,可以用来推断通配符将被如何解析。此库旨在完全模拟AMQP主题通配符的行为,但仍可能存在不足。
实际AMQP语法的文档可以在以下包中找到