mattferris / events
事件调度器
Requires
- mattferris/provider: ~0.3
Requires (Dev)
- phpunit/phpunit: ~4.3
This package is auto-updated.
Last update: 2024-09-29 03:52:30 UTC
README
这是一个包含事件日志器的事件库。它是基于 Udi Dahan 的领域事件模式 构建的。
事件处理
实现从在您的领域创建一个继承自 MattFerris\Events\AbstractDomainEvents
的 DomainEvents
类开始。
namespace MyDomain; class DomainEvents extends \MattFerris\Events\AbstractDomainEvents { }
然后,您可以通过扩展 MattFerris\Events\Event
或实现 MattFerris\Events\EventInterface
来创建单个事件类。Event
是一个空类,所以您的事件类仍然需要提供自己的逻辑。
namespace MyDomain; class SomeEvent extends MattFerris\Events\Event { protected $someArgument; public function __construct($someArgument) { $this->someArgument = $someArgument; } public function getSomeArgument() { return $this->someArgument; } }
要从一个领域实体内部触发/调度事件,请调用 DomainEvents::dispatch()
。
namespace MyDomain; class SomeEntity { public function doSomething() { // stuff happens // dispatch event DomainEvents::dispatch(new SomeEvent($argument)); } }
目前,尚未配置调度器,因此事件不会被任何内容处理。配置调度器可以像这样进行
$dispatcher = new MattFerris\Events\Dispatcher(); MyDomain\DomainEvents::setDispatcher($dispatcher);
现在,您可以将事件监听器添加到调度器。监听器可以是任何 callable
,并且可以监听特定事件或与模式匹配的事件。要匹配特定事件,请使用完全限定类名。
$dispatcher->addListener('MyDomain.SomeEvent', function ($event) { ... });
还可以根据前缀或后缀监听事件。
// listen for all events in the `MyDomain` namespace $dispatcher->addListener('MyDomain.', $handler); // listen for all SomeEvent events in any domain $dispatcher->addListener('.SomeEvent', $handler);
最后,您可以使用星号来监听所有事件。
// listen for all events $dispatcher->addListener('*', $handler);
事件名称
为了灵活性,还可以将监听器分配给监听任意事件名称。在事件触发时,可以将事件名称传递给调度方法的 dispatch 方法。
$dispatcher->addListener('foo.bar', $listener); $dispatcher->dispatch($event, 'foo.bar');
监听器优先级
默认情况下,所有监听器都分配了相同的优先级,并且根据它们添加的顺序调用。也可以为监听器分配优先级,以确保它们比其他监听器更早或更晚调用。优先级是在添加监听器时传递的整数,其中 0
是最高优先级。
// give the listener the highest priority $dispatcher->addListener('*', $listener, 0);
也可以使用优先级常量分配优先级
PRIORITY_HIGH
= 0PRIORITY_NORMAL
= 50PRIORITY_LOW
= 100
// alternatively, you can use the priority constant $dispatcher->addListener('*', $listener, Dispatcher::PRIORITY_HIGH);
事件提供者
可以使用提供者添加事件。简单地创建一个实现 MattFerris\Provider\ProviderInterface
的类,并创建一个名为 provides()
的方法。当传递给调度器的 register()
方法时,将传递一个调度器实例,然后您可以添加监听器。
use MattFerris\Provider\ProviderInterface; use MattFerris\Provider\ConsumerInterface; class EventProvider implements ProviderInterface { public function provides(ConsumerInterface $dispatcher) { $dispatcher->addListener('*', $listener); ... } }
事件日志
通过使用 MattFerris\Events\Logger
来完成事件日志。构造函数接受一个 Dispatcher
实例和一个可调用的函数,该函数将传递结果日志消息,并可以将其写入日志文件、stderr 等。
$logger = new MattFerris\Events\Logger($dispatcher, function ($msg) { error_log($msg); });
就这样!所有触发的事件都将记录到 PHP 的错误日志中。默认情况下,日志消息是事件名称前加上 event:
。例如
event: MattFerris\Events\Event
您可以使用 setPrefix()
更改前缀。
$logger->setPrefix('another prefix: ');
您可以使用日志辅助函数来定制某些事件的日志消息。在您的领域创建一个名为 DomainEventLoggerHelpers
的类,并让它继承 MattFerris\Events\AbstractDomainEventLoggerHelpers
。然后简单地创建静态方法来调用领域事件,其中每个方法返回要记录的字符串。这些方法应该以 on
开头,后面跟着事件名称,例如 onSomeEvent
。
namespace MyDomain; class DomainEventLoggerHelpers extends MattFerris\Events\AbstractDomainEventLoggerHelpers { static public function onSomeEvent(SomeEvent $e) { $foo = $e->getFoo(); $bar = $e->getBar(); return "SomeEvent was dispatched with values foo=$foo, bar=$bar"; } }
将辅助程序注册到日志记录器
MyDomain\DomainEventLoggerHelepers::addHelpers($logger);
现在,当 SomeEvent
触发时,上述辅助程序将被调用,返回的字符串将被记录。
event: SomeEvent was dispatched with values foo=blah, bar=bleh
在我看来,将这些日志辅助程序定义在 MyDomain\DomainEventLoggerHelpers
中是有意义的,因为辅助程序与领域中的事件直接相关。当领域事件更新时,日志辅助程序可以一起更新和提交。