yiisoft / event-dispatcher
Yii 事件分发器
1.1.0
2022-10-27 12:02 UTC
Requires
- php: ^8.0
- psr/event-dispatcher: 1.0.0
Requires (Dev)
- maglnet/composer-require-checker: ^4.2
- phpunit/phpunit: ^9.5
- rector/rector: ^0.14.3
- roave/infection-static-analysis-plugin: ^1.16
- spatie/phpunit-watcher: ^1.23
- vimeo/psalm: ^4.18
Provides
This package is auto-updated.
Last update: 2024-09-17 08:30:22 UTC
README
Yii 事件分发器
兼容 PSR-14 的事件分发器提供分发事件和监听分发事件的能力。
功能
- 兼容 PSR-14
- 简单轻量。
- 鼓励设计事件层次结构。
- 可以组合多个事件监听提供者。
要求
- PHP 8.0 或更高版本。
安装
可以使用 Composer 安装此包。
composer require yiisoft/event-dispatcher
通用用法
该库由两部分组成:事件分发器和事件监听提供者。提供者的任务是注册特定事件类型的监听器。分发器的任务是获取一个事件,从提供者中获取其监听器,并按顺序调用它们。
// 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);
事件分发可能如下所示
use Psr\EventDispatcher\EventDispatcherInterface; final class DocumentProcessor { private EventDispatcherInterface $eventDispatcher; public function __construct(EventDispatcherInterface $eventDispatcher) { $this->eventDispatcher = $eventDispatcher; } public function process(Document $document): void { // Process the document, then dispatch completion event. $this->eventDispatcher->dispatch(new AfterDocumentProcessed($document)); } }
可停止的事件
可以通过实现 Psr\EventDispatcher\StoppableEventInterface
使事件可停止。
final class BusyEvent implements Psr\EventDispatcher\StoppableEventInterface { // ... public function isPropagationStopped(): bool { return true; } }
这样我们可以确保只有第一个事件监听器能够处理事件。另一种选择是允许在某个监听器中停止传播,通过提供相应的事件方法。
事件层次结构
事件故意没有名称或通配符匹配。事件类名称和类/接口层次结构以及组合可以用来实现极大的灵活性。
interface DocumentEvent { } final class BeforeDocumentProcessed implements DocumentEvent { } final class AfterDocumentProcessed implements DocumentEvent { }
使用上述接口监听所有文档相关事件可以这样进行
$listeners->add(static function (DocumentEvent $event) { // log events here });
组合多个监听提供者
如果您想组合多个监听提供者,可以使用 CompositeProvider
。
$compositeProvider = new Yiisoft\EventDispatcher\Provider\CompositeProvider(); $provider = new Yiisoft\EventDispatcher\Provider\Provider($listeners); $compositeProvider->add($provider); $compositeProvider->add(new class implements ListenerProviderInterface { public function getListenersForEvent(object $event): iterable { yield static 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);
分发到多个分发器
可能需要同时通过多个分发器分发事件。这可以像以下这样做
use Yiisoft\EventDispatcher\Dispatcher\CompositeDispatcher; use Yiisoft\EventDispatcher\Dispatcher\Dispatcher; use Yiisoft\EventDispatcher\Provider\ListenerCollection; use Yiisoft\EventDispatcher\Provider\Provider; // Add some listeners. $listeners1 = (new ListenerCollection()) ->add(function (AfterDocumentProcessed $event) { $document = $event->getDocument(); // Do something with document. }); $provider1 = new Provider($listeners1); // Add some listeners. $listeners2 = (new ListenerCollection()) ->add(function (AfterDocumentProcessed $event) { $document = $event->getDocument(); // Do something with document. }); $provider2 = new Provider($listeners2); $dispatcher = new CompositeDispatcher(); $dispatcher->attach(new Dispatcher($provider1)); $dispatcher->attach(new Dispatcher($provider2)); $dispatcher->dispatch(new MyEvent());
文档
如果您需要帮助或有疑问,Yii 论坛 是一个好地方。您还可以查看其他 Yii 社区资源。
许可
Yii 事件分发器是免费软件。它在 BSD 许可证条款下发布。有关更多信息,请参阅 LICENSE
。
由 Yii 软件 维护。
致谢
- Larry Garfield (@crell) 为可调用参数类型的推导提供初始实现。