Subscribers
The package includes EventSubscriberListenerProvider
, which adapts Symfony-style subscribers to the PSR-14
world.
Why Subscribers Are Useful
Subscribers work well when:
- one class should react to several events;
- you want listener priority close to the subscriber definition;
- you are migrating from Symfony conventions;
- you prefer method names over multiple small invokable listener classes.
Direct Provider Usage
use FastForward\EventDispatcher\EventDispatcher;
use FastForward\EventDispatcher\ListenerProvider\EventSubscriberListenerProvider;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
final readonly class SubscriptionActivated
{
public function __construct(
public string $customerEmail,
public string $plan,
) {}
}
final class SubscriptionLifecycleSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
SubscriptionActivated::class => [
['provisionAccess', 20],
['sendReceipt', 10],
],
];
}
public function provisionAccess(SubscriptionActivated $event): void
{
echo 'Provisioning ' . $event->plan . PHP_EOL;
}
public function sendReceipt(SubscriptionActivated $event): void
{
echo 'Sending receipt to ' . $event->customerEmail . PHP_EOL;
}
}
$provider = new EventSubscriberListenerProvider(
new SubscriptionLifecycleSubscriber(),
);
$dispatcher = new EventDispatcher($provider);
$dispatcher->dispatch(new SubscriptionActivated('team@example.com', 'pro'));
Supported getSubscribedEvents()
Shapes
The provider supports the common Symfony formats:
| Shape | Example | Meaning |
|---|---|---|
| single method string | UserRegistered::class => 'onUserRegistered'
|
call one method with default priority 0
|
| method and priority | UserRegistered::class => ['onUserRegistered', 20]
|
call one method with explicit priority |
| many methods for one event | UserRegistered::class => [['sendMail', 20], ['audit', 10]]
|
call several methods in descending priority order |
Subscribers by Event Class or String Name
The event map key may be:
- a class name such as
UserRegistered::class; - an arbitrary string such as
billing.payment_received.
When a subscriber handles a named event, the provider unwraps NamedEvent
and passes the original event
object to the subscriber method.
Priority Rules
Higher priority values run first.
If two subscribers listen to the same event, the provider yields them according to the priority values stored in its internal priority queue.
Class Strings and Instances
You may construct the provider with:
- subscriber instances;
- subscriber class names.
If you provide a class string that does not implement Symfony\Component\EventDispatcher\EventSubscriberInterface
,
the provider throws FastForward\EventDispatcher\Exception\InvalidArgumentException
.
When To Prefer Subscribers
Subscribers are often the best fit when a single bounded context owns several reactions to related events. If each reaction is independent and you want very small classes, invokable listeners or attribute listeners may be clearer.