-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
Symfony version(s) affected
6.1.0
Description
I want to decorate the "event_dispatcher" service and ran into a problem. If I use the exact function signatures of the EventDispatcherInterface, it will result in this error:
App\MyDispatcher::addListener(): Argument #2 ($listener) must be of type callable, array given, called in /var/www/html/project/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php on line 59
I have seen that the function signatures in the EventDispatcher are different. On the addListener function the $listener parameter is from type callable|array:
public function addListener(string $eventName, callable|array $listener, int $priority = 0)
But in the EventDispatcherInterface the "array" is missing:
public function addListener(string $eventName, callable $listener, int $priority = 0);
To fix the error, I could now simply take the signature of the EventDispatcher to my decoration, but then phpstan starts to complain, because the signature of the EventDispatcherInterface is different. Should the signatures of EventDispatcher and EventDispatcherInterface not match?
If that's correct that they don't match, is there any way to decorate the "event_dispatcher" cleanly without phpstan complaining and without including ignore rules?
How to reproduce
- Create a new symfony project:
composer create-project symfony/skeleton:"6.1.*" my-directory
- Create the file
my-directory/src/MyDispatcher.phpwith the following content:
<?php
declare(strict_types=1);
namespace App;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
#[AsDecorator(decorates: 'event_dispatcher', priority: 500)]
class MyDispatcher implements EventDispatcherInterface
{
public function __construct(
private readonly EventDispatcherInterface $innerDispatcher
) {
}
public function dispatch(object $event, string $eventName = null): object
{
return $this->innerDispatcher->dispatch($event, $eventName);
}
public function addListener(string $eventName, callable $listener, int $priority = 0)
{
$this->innerDispatcher->addListener($eventName, $listener, $priority);
}
public function addSubscriber(EventSubscriberInterface $subscriber)
{
$this->innerDispatcher->addSubscriber($subscriber);
}
public function removeListener(string $eventName, callable $listener)
{
$this->innerDispatcher->removeListener($eventName, $listener);
}
public function removeSubscriber(EventSubscriberInterface $subscriber)
{
$this->innerDispatcher->removeSubscriber($subscriber);
}
public function getListeners(string $eventName = null): array
{
return $this->innerDispatcher->getListeners($eventName);
}
public function getListenerPriority(string $eventName, callable $listener): ?int
{
return $this->innerDispatcher->getListenerPriority($eventName, $listener);
}
public function hasListeners(string $eventName = null): bool
{
return $this->innerDispatcher->hasListeners($eventName);
}
}
The function signatures were created by PHPStorm based on the interface and all functions simply call the inner dispatcher function.
-
Execute the command
bin/console debug:container -
This error occurs:
App\MyDispatcher::addListener(): Argument #2 ($listener) must be of type callable, array given, called in /var/www/html/project/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php on line 59
Possible Solution
No response
Additional Context
No response