We use events to perform some tasks if an event occurs, these tasks can be achieved by using the followings:
1. Event Subscriber
2. Event Listeners
Event Subscriber vs Event Listeners
They both serve the same purpose but have different implementations. Both trigger some functions in the specific time of processing data by Symfony.
We can declare multiple functions inside an event subscriber and set the priorities of the functions in the order in which each function will be called. Still, it can’t be achieved in event listeners, so internally Symfony also uses event subscribers over event listeners.
1. Event Subscriber
It is declared as follows:
// src/EventSubscriber/ExceptionSubscriber.php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class ExceptionSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
KernelEvents::EXCEPTION => [
['handleException', 1],
['notifyAdminUser', 2],
],
];
}
public function handleException(ExceptionEvent $event)
{
// ...
}
public function notifyAdminUser(ExceptionEvent $event)
{
// ...
}
}
This event subscriber handles the kernel exceptions like when we do not define routes in our project then this subscriber will be called. Also, we need to register this subscriber in the config/services.yml file.
App\EventSubscriber\ExceptionSubscriber:
tags:
- {doctrine.event_subscriber, connection: default}
The subscriber function with the high number set as priority will be called first and the subscriber function with the lower number set as priority will be called last. Here the function notifyAdminUser will be called and then the function handleException will be called.
2. Event Listener
As explained above the event listener is used for the same reason. It is declared as follows:
// src/EventListener/ExceptionListener.php
namespace App\EventListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class ExceptionListener
{
public function onKernelException(ExceptionEvent $event)
{
$exception = $event->getThrowable();
$message = sprintf(
'Getting following error: %s with code: %s',
$exception->getMessage(),
$exception->getCode()
);
// Customize your response object to display the exception details
$response = new Response();
$response->setContent($message);
// HttpExceptionInterface is a special type of exception that
// holds status code and header details
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
// sends the modified response object to the event
$event->setResponse($response);
}
}
This listener will be called once a kernel exception occurs like calling a route that does not exist. In this case, this listener will be called to handle the exception. Also, we need to register this listener in the config/services.yml file.
services:
App\EventListener\ExceptionListener:
tags:
- { name: kernel.event_listener, event: kernel.exception }
Thanks for reading me. I hope this blog would help you with a better understanding of Symfony subscribers and listeners.