Description
Symfony version(s) affected: 5.3.4, 5.2.12
Description
The "Backport Type Fixes" commit added a callable type declaration to the $listener
parameter of EventDispatcherInterface::addListener()
. Adding that type declaration to implementations will break when using the dependency-injection container. The reason is that the dependency-injection container will generate code that calls addListener
with an array as listener where at index 0 an closure is passed that will resolve to the object that should be called and at index 1 the method name that should be called is passed. According to the official documentation an array is only considered callable if at index 0 of the array the instantiated object is passed, it seems like passing a closure there is not considered to be callable.
How to reproduce
Add a custom EventDispatcher decorater that uses the addListener()
method signature from the interface:
public function addListener(string $eventName, callable $listener, int $priority = 0): void
Or add that native type declaration to the EventDispatcher implementation.
Configure some event subscriber in the service configuration.
After that the dependency-injection container is broken:
Argument 2 passed to EventDispatcher::addListener() must be callable, array given
Possible Solution
Remove the type declaration from the EventDispatcherInterface again.
Or rework the dependency-injection to call EventDispatcherInterface::addListener()
in a way that is compatible with that type declaration.
Additional context
The generated code for the dependency injection container looks like this:
$instance->addListener('kernel.request', [0 => function () {
return ($this->privates['serviceId'] ?? $this->getService());
}, 1 => 'onKernelRequest'], 0);
That seems to not pass the native callable type declaration.