Change subscribed events during runtime (Symfony/Doctrine ED)
Asked Answered
P

1

0

Taking the example from https://symfony.com/doc/current/event_dispatcher.html

class ExceptionSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        return [
            KernelEvents::EXCEPTION => [
                ['processException', 10],
                ['logException', 0],
                ['notifyException', -10],
            ],
        ];
    }
}

Is it correct to assume that this list can be changed during runtime?

E.g.

class ExceptionSubscriber implements EventSubscriberInterface
{
    protected $someToggle = false;

    public static function getSubscribedEvents()
    {
        if ($this->someToggle) {
            return [KernelEvents::EXCEPTION => ['processException']]
        }

        return [
            KernelEvents::EXCEPTION => [
                ['processException', 10],
                ['logException', 0],
                ['notifyException', -10],
            ],
        ]
    }
}

Is this legit and unsubscribes logException and notifyException when I set $someToggle during runtime?

Polish answered 7/4, 2021 at 12:45 Comment(2)
Nope. Not going to work. The static function getSubscribedEvents is called during what Symfony refers to as the 'compile' phase. The information is used to generate php container code. The only way to impact run time stuff would be to access the event dispatcher itself and modify it's listeners. The most straight forward approach would be to let the listeners be called and then let them decide if they should do something or not.Capitally
If you need to do anything like this, do it in the "work part" of your subscriber. Simply exit/return when someToggle === true.Dignity
D
2

No, you cannot change dynamically what events a subscriber listen to by adding logic to the getSubscribedEvents():array method.

That method is run only during a compiler pass when the container is being built, so it will only be executed after cache is cleared.

Trying to change this at runtime will have no effect.

The practical way of doing this is to put this logic into the "work" part of the listener/subscriber:

public function processException(ExceptionEvent $event)
{

    if (!$this->shouldProcessException()) {
        return;
    }
}

The performance hit would be very small or negligible, unless getting the value for shouldProcessException() was otherwise expensive.

Dignity answered 8/4, 2021 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.