In Symfony 4 applications it's recommended to manage events using subscribers instead of listeners because only subscribers are automatically configured when using service autoconfiguration.
However, for those still wanting to use listeners, in Symfony 4.1 we improved
them to support the __invoke()
PHP magic method. Consider the following
service configuration:
1 2 3
# config/services.yaml
App\EventListener\UserListener:
tags: [{ name: kernel.event_listener, event: kernel.request }]
When the kernel.event_listener
tag doesn't define the method
attribute,
Symfony executes the method whose name is on
+ CamelCased event name. In this
example, the onKernelRequest()
method will be executed. In Symfony 4.1, if
the event listener class doesn't define that method, Symfony looks for the
__invoke()
method and executes it if it's found.
In practice, in Symfony 4.1 the UserListener
class could be simply:
1 2 3 4 5 6 7 8 9
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
class UserListener
{
public function __invoke(GetResponseEvent $event)
{
// ...
}
}
Related to this, we've silently added support for __invoke()
in other parts of
the framework, such as the TemplateController
:
1 2 3 4 5 6 7 8 9
# config/routes.yaml
index:
path: /
# before Symfony 4.1 you must add the 'templateAction' method name
controller: 'Symfony\Bundle\FrameworkBundle\Controller\TemplateController::templateAction'
# starting from Symfony 4.1, TemplateController includes an __invoke() method
controller: 'Symfony\Bundle\FrameworkBundle\Controller\TemplateController'
defaults:
template: 'homepage.html.twig'
TemplateController
change was also 4.1?@Chris you are right! It was merged on December 4 (https://github.com/symfony/symfony/pull/24637) so it's not included in Symfony 3.4/4.0 but 4.1. I've updated the article. Thanks!
Really good news, finally we can create a Listener which can listen to a single event without creating an "on" method.
Question, does this approach works with Subscriber?
Question, does this approach works with Subscriber?
Technically yes, but for a subscriber (your class indicates which events it listeners for) so you need to specify the method you want to call. Not sure if __invoke is automatically used here. Best to have a look at the code to know for sure :)
Question, does this approach works with Subscriber?
Yes, this will work :
public static function getSubscribedEvents() { return [ KernelEvents::REQUEST => '__invoke' ]; }
But IMHO you should give more meaningful names to your methods.