The Routing Component

    Note

    If you install this component outside of a Symfony application, you mustrequire the file in your code to enable the classautoloading mechanism provided by Composer. Readthis article for more details.

    Usage

    The main Symfony routing article explains all the features ofthis component when used inside a Symfony application. This article onlyexplains the things you need to do to use it in a non-Symfony PHP application.

    A routing system has three parts:

    • A , which contains theroute definitions (instances of the class Route);
    • A , which has informationabout the request;
    • A UrlMatcher, which performsthe mapping of the path to a single route.Here is a quick example:
    1. use App\Controller\BlogController;
    2. use Symfony\Component\Routing\Generator\UrlGenerator;
    3. use Symfony\Component\Routing\Matcher\UrlMatcher;
    4. use Symfony\Component\Routing\RequestContext;
    5. use Symfony\Component\Routing\Route;
    6. use Symfony\Component\Routing\RouteCollection;
    7.  
    8. $route = new Route('/blog/{slug}', ['_controller' => BlogController::class]);
    9. $routes = new RouteCollection();
    10. $routes->add('blog_show', $route);
    11.  
    12. $context = new RequestContext('/');
    13.  
    14. // Routing can match routes with incoming requests
    15. $matcher = new UrlMatcher($routes, $context);
    16. $parameters = $matcher->match('/blog/lorem-ipsum');
    17. // $parameters = [
    18. // '_controller' => 'App\Controller\BlogController',
    19. // 'slug' => 'lorem-ipsum',
    20. // '_route' => 'blog_show'
    21. // ]
    22.  
    23. // Routing can also generate URLs for a given route
    24. $generator = new UrlGenerator($routes, $context);
    25. $url = $generator->generate('blog_show', [
    26. 'slug' => 'my-blog-post',
    27. ]);
    28. // $url = '/blog/my-blog-post'

    The method takes two arguments. The first is the name of the route. The secondis a Route object, which expects aURL path and some array of custom variables in its constructor. This arrayof custom variables can be anything that's significant to your application,and is returned when that route is matched.

    The returns the variables you set on the route as well as the route parameters.Your application can now use this information to continue processing the request.In addition to the configured variables, a _route key is added, which holdsthe name of the matched route.

    If no matching route can be found, aResourceNotFoundException willbe thrown.

    Defining Routes

    A full route definition can contain up to eight parts:

    1. $route = new Route(
    2. '/archive/{month}', // path
    3. ['_controller' => 'showArchive'], // default values
    4. ['month' => '[0-9]{4}-[0-9]{2}', 'subdomain' => 'www|m'], // requirements
    5. [], // options
    6. '{subdomain}.example.com', // host
    7. [], // schemes
    8. [], // methods
    9. );
    10.  
    11. // ...
    12.  
    13. $parameters = $matcher->match('/archive/2012-01');
    14. // [
    15. // '_controller' => 'showArchive',
    16. // 'month' => '2012-01',
    17. // 'subdomain' => 'www',
    18. // '_route' => ...
    19. // ]
    20.  
    21. $parameters = $matcher->match('/archive/foo');
    22. // throws ResourceNotFoundException

    You can add routes or other instances ofRouteCollection to another collection.This way you can build a tree of routes. Additionally you can define commonoptions for all routes of a subtree using methods provided by theRouteCollection class:

    1. $rootCollection = new RouteCollection();
    2.  
    3. $subCollection = new RouteCollection();
    4. $subCollection->add(...);
    5. $subCollection->add(...);
    6. $subCollection->addPrefix('/prefix');
    7. $subCollection->addDefaults([...]);
    8. $subCollection->addRequirements([...]);
    9. $subCollection->addOptions([...]);
    10. $subCollection->setHost('{subdomain}.example.com');
    11. $subCollection->setMethods(['POST']);
    12. $subCollection->setSchemes(['https']);
    13. $subCollection->setCondition('context.getHost() matches "/(secure|admin).example.com/"');
    14.  
    15. $rootCollection->addCollection($subCollection);

    Setting the Request Parameters

    Normally you can pass the values from the $SERVER variable to populate theRequestContext. But if you use the[_HttpFoundation]($e202783772dc89dd.md) component, you can use its class to feed theRequestContext in a shortcut:

    1. use Symfony\Component\HttpFoundation\Request;
    2.  
    3. $context = new RequestContext();
    4. $context->fromRequest(Request::createFromGlobals());

    The Routing component comes with a number of loader classes, each giving you theability to load a collection of route definitions from external resources.

    Each loader expects a instanceas the constructor argument. You can use the FileLocatorto define an array of paths in which the loader will look for the requested files.If the file is found, the loader returns a .

    If you're using the YamlFileLoader, then route definitions look like this:

    1. # routes.yaml
    2. route1:
    3. path: /foo
    4. controller: MyController::fooAction
    5. methods: GET|HEAD
    6. route2:
    7. path: /foo/bar
    8. controller: FooBarInvokableController
    9. methods: PUT

    To load this file, you can use the following code. This assumes that yourroutes.yaml file is in the same directory as the below code:

    1. use Symfony\Component\Config\FileLocator;
    2. use Symfony\Component\Routing\Loader\YamlFileLoader;
    3.  
    4. // looks inside *this* directory
    5. $fileLocator = new FileLocator([__DIR__]);
    6. $loader = new YamlFileLoader($fileLocator);
    7. $routes = $loader->load('routes.yaml');

    Besides YamlFileLoader there are twoother loaders that work the same way:

    • If you use the PhpFileLoader youhave to provide the name of a PHP file which returns a callable handling a.This class allows to chain imports, collections or simple route definition calls:

    There is also the ClosureLoader, whichcalls a closure and uses the result as a :

    1.  
    2. $closure = function () {
    3. return new RouteCollection();
    4. };
    5.  
    6. $loader = new ClosureLoader();
    7. $routes = $loader->load($closure);

    1. use Doctrine\Common\Annotations\AnnotationReader;
    2. use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
    3. use Symfony\Component\Config\FileLocator;
    4. use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
    5.  
    6. $loader = new AnnotationDirectoryLoader(
    7. new FileLocator(__DIR__.'/app/controllers/'),
    8. new AnnotatedRouteControllerLoader(
    9. new AnnotationReader()
    10. )
    11. );
    12.  
    13. $routes = $loader->load(__DIR__.'/app/controllers/');
    14. // ...

    Note

    In order to use the annotation loader, you should have installed thedoctrine/annotations and doctrine/cache packages with Composer.

    Tip

    Annotation classes aren't loaded automatically, so you must load themusing a class loader like this:

    1. use Composer\Autoload\ClassLoader;
    2. use Doctrine\Common\Annotations\AnnotationRegistry;
    3.  
    4. /** @var ClassLoader $loader */
    5. $loader = require __DIR__.'/../vendor/autoload.php';
    6.  
    7. AnnotationRegistry::registerLoader([$loader, 'loadClass']);
    8.  
    9. return $loader;

    The Router class is an all-in-one packageto use the Routing component. The constructor expects a loader instance,a path to the main route definition and some other settings:

    With the cache_dir option you can enable route caching (if you provide apath) or disable caching (if it's set to null). The caching is doneautomatically in the background if you want to use it. A basic example of the class would look like:

    1. $fileLocator = new FileLocator([__DIR__]);
    2. $requestContext = new RequestContext('/');
    3.  
    4. $router = new Router(
    5. new YamlFileLoader($fileLocator),
    6. 'routes.yaml',
    7. ['cache_dir' => __DIR__.'/cache'],
    8. $requestContext
    9. );
    10. $parameters = $router->match('/foo/bar');
    11. $url = $router->generate('some_route', ['parameter' => 'value']);

    Note

    If you use caching, the Routing component will compile new classes whichare saved in the cache_dir. This means your script must have writepermissions for that location.

    Learn more