Logan Bailey

Adventures In Web Development

Blog, About, GitHub, and LinkedIn

Symfony 2's Routing Component route matching works off the simple concept; return the matching route or throw an exception. It comes with 5 standard exceptions, the most common being RouteNotFoundException.

Unfortunately, the standard Symfony UrlMatcher throws a RouteNotFoundException if the url does not match any routes or if a routes protocol was set HTTPS and the request was HTTP. This prevents developers from correctly redirecting HTTP to HTTPS urls. Luckily, the routing component ships with another matcher, RedirectableUrlMatcher. Since this is an abstract class, you must define your own child class and implement redirect method. The method takes 3 parameters $path, $route, and $scheme; the return value will be the return value of the match method. In Silex's implementation the correct URL is returned with some sugar to make the page redirect; I prefer to throw a custom exception. I believe that this is more consistent with the how the match method handles other invalid requests; which throws an MethodNotAllowedException when POST is used on a GET request. I've included my code on how I would handle such an exception. The Silex example shows a good way to build the correct URL.

    use MyApp\RedirectableUrlMatcher; 
    use MyApp\Exception\HTTPRedirectException; 
    use Symfony\Component\HttpFoundation\Request; 
    use Symfony\Component\Routing\Exception\RouteNotFoundException; 
    $context = new RequestContext(); 
    $context->fromRequest(Request::createFromGlobals()); 
    // $routes is an instance of RouteCollection 
    try {
    	$matcher = new RedirectableUrlMatcher($routes, $context); 
    	$route = $matcher->match($context->getPathInfo()); 
    } catch (RouteNotFoundException $e) { 
    	// Show 404 Page 
    } catch (HTTPRedirectException $e) { 
    	// HTTPRedirectException is a child of Exception 
    	// where the message is the URL to redirect to 
    	header('location: ' . $e->getMessage()); 
    	exit;
    }