lubobill1990 / event-dispatcher
Yii 事件调度器
dev-master / 3.0.x-dev
2020-08-24 17:02 UTC
Requires
- php: ^7.4|^8.0
- psr/event-dispatcher: 1.0.0
Requires (Dev)
- infection/infection: ^0.16.3
- phan/phan: ^3.0
- phpunit/phpunit: ^9.3
Provides
This package is auto-updated.
Last update: 2024-08-25 02:08:47 UTC
README
Yii 事件调度器
符合PSR-14的事件调度器提供了分发事件和监听分发事件的特性。
特性
- 符合PSR-14
- 简单轻量
- 鼓励设计事件层次结构
- 可以组合多个事件监听提供者
通用用法
该库由两部分组成:事件调度器和事件监听提供者。提供者的任务是为特定事件类型注册监听器。调度器的任务是获取一个事件,从提供者那里获取该事件的监听器,并按顺序调用它们。
// add some listeners $listeners = (new \Yiisoft\EventDispatcher\Provider\ListenerCollection()) ->add(function (AfterDocumentProcessed $event) { $document = $event->getDocument(); // do something with document }); $provider = new Yiisoft\EventDispatcher\Provider\Provider($listeners); $dispatcher = new Yiisoft\EventDispatcher\Dispatcher\Dispatcher($provider);
事件分发可能看起来像
class DocumentProcessor { public function process(Document $document) { // process the document $dispatcher->dispatch(new AfterDocumentProcessed($document)); } }
可停止的事件
通过实现Psr\EventDispatcher\StoppableEventInterface
,可以将事件设置为可停止的
class BusyEvent implements Psr\EventDispatcher\StoppableEventInterface { // ... public function isPropagationStopped(): bool { return true; } }
这样我们就可以确保只有第一个事件监听器能够处理事件。另一种选择是允许在某个监听器中提供相应的事件方法来停止传播。
事件层次结构
出于故意,事件没有名称或通配符匹配。可以使用事件类名称和类/接口层次结构以及组合来实现很大的灵活性
interface DocumentEvent { } class BeforeDocumentProcessed implements DocumentEvent { } class AfterDocumentProcessed implements DocumentEvent { }
使用上述接口,可以监听所有与文档相关的事件
$listeners->add(function (DocumentEvent $event) { // log events here });
组合多个监听提供者
如果您想组合多个监听提供者,可以使用CompositeProvider
$compositeProvider = new Yiisoft\EventDispatcher\Provider\CompositeProvider(); $provider = new Yiisoft\EventDispatcher\Provider\Provider(); $compositeProvider->add($provider); $compositeProvider->add(new class implements ListenerProviderInterface { public function getListenersForEvent(object $event): iterable { yield function ($event) { // handle }; } }); $dispatcher = new Yiisoft\EventDispatcher\Dispatcher\Dispatcher($compositeProvider);
使用具体事件名称注册监听器
您可以使用更简单的监听提供者,允许您指定它们可以提供哪些事件。
在某些特定情况下可能很有用,例如,如果其中一个监听器不需要传递事件对象作为参数(如果监听器只需要在运行时特定阶段运行,但不需要事件数据)。
在这种情况下,如果您需要包含在此库中的两个提供者的功能,建议使用聚合(参见上面)。
$listeners = (new \Yiisoft\EventDispatcher\Provider\ListenerCollection()) ->add(static function () { // this function does not need an event object as argument }, SomeEvent::class);
单元测试
该包使用PHPUnit进行测试。要运行测试
./vendor/bin/phpunit
突变测试
该包的测试使用Infection突变框架进行检查。要运行它
./vendor/bin/infection
静态分析
使用Phan对代码进行静态分析。要运行静态分析
./vendor/bin/phan
致谢
- Larry Garfield (@crell) 对可调用参数类型的初始实现表示感谢。