jmikola/wildcard-event-dispatcher

受AMQP主题交换启发的支持通配符模式的事件派发器。

2.0.1 2023-08-22 18:42 UTC

This package is auto-updated.

Last update: 2024-08-22 20:49:01 UTC


README

Build Status

此库实现了一个基于Symfony接口的事件派发器,受AMQP主题交换的通配符语法启发。监听器可以绑定到通配符模式,并在派发的事件名称与该模式匹配时被通知。仍然支持字面事件名称匹配。

注意:此库使用的通配符语法与在Symfony 4.3中引入的简化事件派发不兼容,该语法使用事件的全限定名称(FQCN)而不是自定义字符串(例如 core.request)。

如果您有兴趣在Symfony项目中使用此库,您还可以查看相应的扩展包

安装

此库作为发布,可以通过Composer安装。

$ 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.barcore事件。上述core.*模式将无法捕获此事件。您可以使用以下语法:

<?php

$coreListener = function(Event $e) {};

$dispatcher = new WildcardEventDispatcher();
$dispatcher->addListener('core.*.*', $coreListener);

此语法将匹配core.foocore.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语法的文档可以在以下包中找到