Saving the last matched route
Scenario
I’d like to redirect to the last request. For example, I have a form accesible from multiple pages and after submission I want to redirect the use to the page where he or she came from.
Solution #1: HTTP Referer
The correct spelling is Referrer, but a small error made in RFC 1945 (HTTP/1.0 specification). Widely used since then, the Referer spelling is the only possible in context of HTTP.
<?php
use Symfony\Component\HttpFoundation\RedirectResponse;
class Controller
{
public function refererAction()
{
$referer = $request->headers->get('referer');
return new RedirectResponse($referer);
}
}
The referer might not be available in the request and user agents are not required to pass it along with the request. A safer way is to store the last request in the session.
Solution #2: Saving the last route in the session
Storing the last matched route in the session is more reliable than detecting the HTTP_REFERER
header. To store the route, we will create an EventListener
, which will be called during each kernel.request
event. The same event is used for the RouterListener
, which actually matches the path in the URL to a route. To make sure the appropriate route is already found, we have to give our listener a lower priority. RouterListener
has priority 32, so we choose a lower number.
services:
smf_example.last_route_event_listener:
class: SmfBlog\ExampleBundle\EventListener\LastRouteListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 30 }
<?php
namespace SmfBlog\ExampleBundle\EventListener;
use Symfony\Component\HttpFoundation\Session;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
class LastRouteListener
{
public function onKernelRequest(GetResponseEvent $event)
{
// Do not save subrequests
if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
return;
}
$request = $event->getRequest();
$session = $request->getSession();
$routeName = $request->get('_route');
$routeParams = $request->get('_route_params');
if ($routeName[0] == '_') {
return;
}
$routeData = ['name' => $routeName, 'params' => $routeParams];
// Do not save same matched route twice
$thisRoute = $session->get('this_route', []);
if ($thisRoute == $routeData) {
return;
}
$session->set('last_route', $thisRoute);
$session->set('this_route', $routeData);
}
}