Symfony
sponsored by SensioLabs
Menu
  • About
  • Documentation
  • Screencasts
  • Cloud
  • Certification
  • Community
  • Businesses
  • News
  • Download
  1. Home
  2. Documentation
  3. Components
  4. The Routing Component
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud
Search by Algolia

Table of Contents

  • Installation
  • Usage
  • Routing System Setup
  • Defining Routes
  • Route Collections
  • Setting the Request Parameters
  • Loading Routes
    • File Routing Loaders
    • Closure Routing Loaders
    • Annotation Routing Loaders
    • The all-in-one Router
  • Learn more

The Routing Component

Edit this page

Warning: You are browsing the documentation for Symfony 4.3, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

The Routing Component

The Routing component maps an HTTP request to a set of configuration variables. It's used to build routing systems for web applications where each URL is associated with some code to execute.

Installation

1
$ composer require symfony/routing

Note

If you install this component outside of a Symfony application, you must require the vendor/autoload.php file in your code to enable the class autoloading mechanism provided by Composer. Read this article for more details.

Usage

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

Routing System Setup

A routing system has three parts:

  • A RouteCollection, which contains the route definitions (instances of the Route class);
  • A RequestContext, which has information about the request;
  • A UrlMatcher, which performs the mapping of the path to a single route.

Here is a quick example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use App\Controller\BlogController;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

$route = new Route('/blog/{slug}', ['_controller' => BlogController::class]);
$routes = new RouteCollection();
$routes->add('blog_show', $route);

$context = new RequestContext('/');

// Routing can match routes with incoming requests
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match('/blog/lorem-ipsum');
// $parameters = [
//     '_controller' => 'App\Controller\BlogController',
//     'slug' => 'lorem-ipsum',
//     '_route' => 'blog_show'
// ]

// Routing can also generate URLs for a given route
$generator = new UrlGenerator($routes, $context);
$url = $generator->generate('blog_show', [
    'slug' => 'my-blog-post',
]);
// $url = '/blog/my-blog-post'

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

The UrlMatcher::match() 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 holds the name of the matched route.

If no matching route can be found, a ResourceNotFoundException will be thrown.

Defining Routes

A full route definition can contain up to eight parts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$route = new Route(
    '/archive/{month}', // path
    ['_controller' => 'showArchive'], // default values
    ['month' => '[0-9]{4}-[0-9]{2}', 'subdomain' => 'www|m'], // requirements
    [], // options
    '{subdomain}.example.com', // host
    [], // schemes
    [], // methods
    'context.getHost() matches "/(secure|admin).example.com/"' // condition
);

// ...

$parameters = $matcher->match('/archive/2012-01');
// [
//     '_controller' => 'showArchive',
//     'month' => '2012-01',
//     'subdomain' => 'www',
//     '_route' => ...
// ]

$parameters = $matcher->match('/archive/foo');
// throws ResourceNotFoundException

Route Collections

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$rootCollection = new RouteCollection();

$subCollection = new RouteCollection();
$subCollection->add(...);
$subCollection->add(...);
$subCollection->addPrefix('/prefix');
$subCollection->addDefaults([...]);
$subCollection->addRequirements([...]);
$subCollection->addOptions([...]);
$subCollection->setHost('{subdomain}.example.com');
$subCollection->setMethods(['POST']);
$subCollection->setSchemes(['https']);
$subCollection->setCondition('context.getHost() matches "/(secure|admin).example.com/"');

$rootCollection->addCollection($subCollection);

Setting the Request Parameters

The RequestContext provides information about the current request. You can define all parameters of an HTTP request with this class via its constructor:

1
2
3
4
5
6
7
8
9
10
public function __construct(
    $baseUrl = '',
    $method = 'GET',
    $host = 'localhost',
    $scheme = 'http',
    $httpPort = 80,
    $httpsPort = 443,
    $path = '/',
    $queryString = ''
)

Normally you can pass the values from the $_SERVER variable to populate the RequestContext. But if you use the HttpFoundation component, you can use its Request class to feed the RequestContext in a shortcut:

1
2
3
4
use Symfony\Component\HttpFoundation\Request;

$context = new RequestContext();
$context->fromRequest(Request::createFromGlobals());

Loading Routes

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

File Routing Loaders

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

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

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

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

1
2
3
4
5
6
7
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;

// looks inside *this* directory
$fileLocator = new FileLocator([__DIR__]);
$loader = new YamlFileLoader($fileLocator);
$routes = $loader->load('routes.yaml');

Besides YamlFileLoader there are two other loaders that work the same way:

  • XmlFileLoader
  • PhpFileLoader

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

1
2
3
4
5
6
7
8
9
// RouteProvider.php
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

return function (RoutingConfigurator $routes) {
    $routes->add('route_name', '/foo')
        ->controller('ExampleController')
        // ...
    ;
};

Closure Routing Loaders

There is also the ClosureLoader, which calls a closure and uses the result as a RouteCollection:

1
2
3
4
5
6
7
8
use Symfony\Component\Routing\Loader\ClosureLoader;

$closure = function () {
    return new RouteCollection();
};

$loader = new ClosureLoader();
$routes = $loader->load($closure);

Annotation Routing Loaders

Last but not least there are AnnotationDirectoryLoader and AnnotationFileLoader to load route definitions from class annotations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;

$loader = new AnnotationDirectoryLoader(
    new FileLocator(__DIR__.'/app/controllers/'),
    new AnnotatedRouteControllerLoader(
        new AnnotationReader()
    )
);

$routes = $loader->load(__DIR__.'/app/controllers/');
// ...

Note

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

Tip

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

1
2
3
4
5
6
7
8
9
use Composer\Autoload\ClassLoader;
use Doctrine\Common\Annotations\AnnotationRegistry;

/** @var ClassLoader $loader */
$loader = require __DIR__.'/../vendor/autoload.php';

AnnotationRegistry::registerLoader([$loader, 'loadClass']);

return $loader;

The all-in-one Router

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

1
2
3
4
5
6
7
public function __construct(
    LoaderInterface $loader,
    $resource,
    array $options = [],
    RequestContext $context = null,
    LoggerInterface $logger = null
);

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

1
2
3
4
5
6
7
8
9
10
11
$fileLocator = new FileLocator([__DIR__]);
$requestContext = new RequestContext('/');

$router = new Router(
    new YamlFileLoader($fileLocator),
    'routes.yaml',
    ['cache_dir' => __DIR__.'/cache'],
    $requestContext
);
$parameters = $router->match('/foo/bar');
$url = $router->generate('some_route', ['parameter' => 'value']);

Note

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

Learn more

  • Routing
  • How to Create a custom Route Loader
  • Looking up Routes from a Database: Symfony CMF DynamicRouter
  • Controller
  • Extending Action Argument Resolving
  • How to Customize Error Pages
  • How to Forward Requests to another Controller
  • How to Define Controllers as Services
  • How to Create a SOAP Web Service in a Symfony Controller
  • How to Upload Files
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
We stand with Ukraine.
Version:
Code consumes server resources. Blackfire tells you how

Code consumes server resources. Blackfire tells you how

Peruse our complete Symfony & PHP solutions catalog for your web development needs.

Peruse our complete Symfony & PHP solutions catalog for your web development needs.

↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

Avatar of Vincent Godé, a Symfony contributor

Thanks Vincent Godé for being a Symfony contributor

2 commits • 4 lines changed

View all contributors that help us make Symfony

Become a Symfony contributor

Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

Learn how to contribute

Symfony™ is a trademark of Symfony SAS. All rights reserved.

  • What is Symfony?
    • Symfony at a Glance
    • Symfony Components
    • Case Studies
    • Symfony Releases
    • Security Policy
    • Logo & Screenshots
    • Trademark & Licenses
    • symfony1 Legacy
  • Learn Symfony
    • Symfony Docs
    • Symfony Book
    • Reference
    • Bundles
    • Best Practices
    • Training
    • eLearning Platform
    • Certification
  • Screencasts
    • Learn Symfony
    • Learn PHP
    • Learn JavaScript
    • Learn Drupal
    • Learn RESTful APIs
  • Community
    • SymfonyConnect
    • Support
    • How to be Involved
    • Code of Conduct
    • Events & Meetups
    • Projects using Symfony
    • Downloads Stats
    • Contributors
    • Backers
  • Blog
    • Events & Meetups
    • A week of symfony
    • Case studies
    • Cloud
    • Community
    • Conferences
    • Diversity
    • Documentation
    • Living on the edge
    • Releases
    • Security Advisories
    • SymfonyInsight
    • Twig
    • SensioLabs
  • Services
    • SensioLabs services
    • Train developers
    • Manage your project quality
    • Improve your project performance
    • Host Symfony projects
    Deployed on
Follow Symfony
Search by Algolia