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.php
with 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