Alexander M. Turek
Contributed by Alexander M. Turek in #33851

Symfony triggers several events during the request-response flow. Event listeners and event subscribers allow you to execute some code to respond to those events.

Event subscribers are usually preferred because they can listen to multiple events and they don't require any configuration when using autoconfiguration. In Symfony 4.4 we've improved event listeners to make them easier to configure.

First, remove the event attribute of the kernel.event_listener tag used when registering the listener:

1
2
3
4
5
6
# config/services.yaml
services:
    App\EventListener\MyRequestListener:
        tags:
-            - { name: kernel.event_listener, event: kernel.request }
+            - { name: kernel.event_listener }

Then, make sure that your event listener uses a method named after the event (onKernelRequest() in this example) or __invoke() to avoid having to define the event listener method in the kernel.event_listener tag:

1
2
3
4
5
6
7
8
9
10
11
namespace App\EventListener;

use Symfony\Component\HttpKernel\Event\RequestEvent;

final class MyRequestListener
{
    public function __invoke(RequestEvent $event): void
    {
        // ...
    }
}

That's all. Symfony will now introspect the arguments of the listener method (RequestEvent in this example) to know which event is the event listener associated to.

Thanks to this simplified configuration, you can remove the configuration of all your event listeners and replace it by the following, which will register all event listeners at once:

1
2
3
4
5
# config/services.yaml
services:
    App\EventListener\:
        resource: ../src/EventListener/*
        tags: [kernel.event_listener]

Invokable Doctrine Entity Listeners

Thomas Calvet
Contributed by Thomas Calvet in #32486

Doctrine entity listeners are one of the several ways to work with Doctrine events. In Symfony 4.4 we've also improved them to allow using the __invoke() magic PHP method to define the logic of the listener:

1
2
3
4
5
6
7
8
9
10
11
12
namespace App\EventListener;

use App\Entity\User;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

class UserChangedNotifier
{
    public function __invoke(User $user, LifecycleEventArgs $event)
    {
        // ...
    }
}

This way you don't have to define a custom method attribute in the doctrine.orm.entity_listener tag used to register the listener:

1
2
3
4
5
6
7
8
9
10
11
12
services:
    # ...

    App\EventListener\UserChangedNotifier:
        tags:
            -
                name: 'doctrine.orm.entity_listener'
                entity: 'App\Entity\User'
                # before, when not defining the method name, Symfony looked for
                # a method called after the event (e.g. 'postUpdate()') Now it
                # will also look for an '__invoke()' method
                event: 'postUpdate'
Published in #Living on the edge