componenta/event
Composer 安装命令:
composer require componenta/event
包简介
PSR-14 compliant event dispatcher with prioritized and composite listener providers
README 文档
README
Minimal PSR-14 event dispatcher with prioritized and composite listener providers. Mutable providers with unsubscribe tokens, immutable dispatcher.
Installation
composer require componenta/event
Requirements
- PHP 8.4+
psr/event-dispatcher^1.0
Related Packages
| Package | Why it matters here |
|---|---|
psr/event-dispatcher |
Defines the PSR-14 dispatcher and listener-provider interfaces. |
componenta/auth |
Can publish authentication and session lifecycle events. |
componenta/cqrs |
Can publish command lifecycle events through EventMiddleware. |
componenta/error-handler |
Can report errors through listeners. |
componenta/di |
Can create listeners from the application container. |
Quick Start
use Componenta\Event\EventDispatcher; use Componenta\Event\Provider\ListenerProvider; $provider = new ListenerProvider(); $provider->addListener(UserRegistered::class, fn(UserRegistered $e) => sendWelcomeEmail($e->user)); $dispatcher = new EventDispatcher($provider); $dispatcher->dispatch(new UserRegistered($user));
Components
EventDispatcher
Final, readonly PSR-14 dispatcher. The provider reference is shared — listeners registered later are visible to all dispatches.
$dispatcher = new EventDispatcher($provider); $event = $dispatcher->dispatch(new OrderPlaced(...)); // returns the event $fork = $dispatcher->withProvider($otherProvider); // new instance
Events implementing Psr\EventDispatcher\StoppableEventInterface halt propagation when isPropagationStopped() becomes true. An already-stopped event skips all listeners.
ListenerProvider
Plain listener registry keyed by event class. addListener() returns an unsubscribe closure.
$provider = new ListenerProvider(); $off = $provider->addListener(PostPublished::class, $handler); $off(); // removes the listener $provider->removeListener(PostPublished::class, $handler); // bool $provider->has(PostPublished::class); // bool $provider->contains(PostPublished::class, $handler); // bool
PrioritizedProvider
Listeners are dispatched in priority order. Sorting is lazy and cache-aware — adding a listener after a dispatch invalidates the cached order.
use Componenta\Event\Provider\PrioritizedProvider; use Componenta\Event\Provider\SortMode; $provider = new PrioritizedProvider(mode: SortMode::DESC); // default $provider->addListener(CommentPosted::class, $auditHandler, priority: 100); $provider->addListener(CommentPosted::class, $defaultHandler); // 0 by default
Priorities are resolved in this order: explicit $priority argument → PrioritizedListenerInterface::$priority → 0. Listeners with equal priority are dispatched in registration order (stable sort).
PrioritizedListenerInterface
Invokable listeners can expose their own priority:
use Componenta\Event\Provider\PrioritizedListenerInterface; final class LogAuditEvent implements PrioritizedListenerInterface { public int $priority { get => 1000; } public function __invoke(AuditEvent $event): void { /* ... */ } } $provider->addListener(AuditEvent::class, new LogAuditEvent()); // priority 1000 from interface
CompositeProvider
Aggregates multiple providers into one. contains() is recursive; has() works across EventTypeAwareProviderInterface children.
use Componenta\Event\Provider\CompositeProvider; $composite = new CompositeProvider([$coreProvider, $moduleProvider]); $composite->add($pluginProvider); $dispatcher = new EventDispatcher($composite);
Bulk Registration
$provider->addListeners([ PostPublished::class => [$sendDigest, $updateIndex], CommentPosted::class => $notifyAuthor, ]); // Prioritized: [callable, int] pairs or bare callables within one group $prio->addListeners([ AuditEvent::class => [ [$rotateLogs, 100], [$persistAudit, 50], $defaultLogger, // priority 0 or from interface ], ]);
Patterns
One-shot listener
$off = null; $off = $provider->addListener(Booted::class, function (Booted $e) use (&$off) { $off(); // unsubscribe before running (re-entrancy safe) initialize($e); });
Scoped subscription
function withTemporaryListener(ListenerProvider $p, string $event, callable $h, callable $block): mixed { $off = $p->addListener($event, $h); try { return $block(); } finally { $off(); } }
Reference
| Symbol | Purpose |
|---|---|
EventDispatcher |
PSR-14 dispatcher, final readonly |
ListenerProvider |
Plain keyed-by-event-class registry |
PrioritizedProvider |
Priority-ordered registry with lazy sort |
CompositeProvider |
Aggregate of child providers, recursive contains |
EventTypeAwareProviderInterface |
Contract for providers that expose has(eventType) |
PrioritizedListenerInterface |
Listener-side priority declaration |
SortMode |
ASC / DESC for PrioritizedProvider |
All mutable providers expose: addListener, addListeners, removeListener, contains, has. addListener returns an unsubscribe Closure.
License
MIT
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-14