Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Problems decorating the "event_dispatcher" service #48130

Copy link
Copy link
Closed
@momocode-de

Description

@momocode-de
Issue body actions

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

  1. Create a new symfony project:
composer create-project symfony/skeleton:"6.1.*" my-directory
  1. 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.

  1. Execute the command bin/console debug:container

  2. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.