Search code examples
phpsymfonysymfony-routing

Super simple framework 301 redirect from Symfony routes


I try to build super simple framework. I don't want to use constrollers... basicly everything works good and this is great start for simple websites but I want one more feature that I have problems with.

I try to achieve as simple as possible solution to add in routes pages with 301 redirect. For example I want /facebook with 301 to http://facebook.com/example.

Here is my code... index.php below:

<?php

require_once __DIR__.'/../vendor/autoload.php';

$dotenv = new Dotenv\Dotenv(__DIR__.'/../');
$dotenv->load();

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing;

$request = Request::createFromGlobals();
$routes = include __DIR__.'/../routes/web.php';

$context = new Routing\RequestContext();
$context->fromRequest($request);
$matcher = new Routing\Matcher\UrlMatcher($routes, $context);

try {
    extract($matcher->match($request->getPathInfo()), EXTR_SKIP);
    ob_start();
    include sprintf(__DIR__.'/../resources/views/%s.php', $_route);

    $response = new Response(ob_get_clean());
} catch (Routing\Exception\ResourceNotFoundException $e) {
    $response = new Response();
    $response->setStatusCode(404);
    include __DIR__.'/../resources/views/errors/404.php';
} catch (Exception $e) {
    $response = new Response();
    $response->setStatusCode(500);
    include __DIR__.'/../resources/views/errors/500.php';
}

$response->send();

And my routes.php code:

<?php

use Symfony\Component\Routing;

$routes = new Routing\RouteCollection();

// 200

$routes->add('index', new Routing\Route('/'));
$routes->add('index', new Routing\Route('/about'));
$routes->add('index', new Routing\Route('/contact'));

// 301

// redirect from /facebook to -> http://facebook.com/example
// redirect from /twitter to -> http://twitter.com/example

return $routes;

Now I can make specific file for that route just like for the others and inside that file I can add header php redirect... but this is tedious approach. What can I do to define that redirect inside routes directly?


Solution

  • In your case you can do the following:

    //routes.php
    
    use Symfony\Component\HttpFoundation\RedirectResponse;
    
    $permanentRedirect = function ($url) {
        return new RedirectResponse($url, 301);
    };
    
    //...
    
    $routes->add('facebook', new Routing\Route('/facebook', array(
        '_controller' => $permanentRedirect,
        'url' => 'http://facebook.com/example',
    )));
    
    //...
    
    return $routes;
    

    Next, in your index.php:

    //...
    
    try {
        extract($matcher->match($request->getPathInfo()), EXTR_SKIP);
    
        if (isset($_controller) && isset($url)) {
            $response = call_user_func($_controller, $url);
        } else {
            ob_start();
            include sprintf(__DIR__.'/../resources/views/%s.php', $_route);
    
            $response = new Response(ob_get_clean());
        }        
    } catch (Routing\Exception\ResourceNotFoundException $e) {
        //...
    } catch (Exception $e) {
        //...
    }