Symfony
sponsored by SensioLabs
Menu
  • About
  • Documentation
  • Screencasts
  • Cloud
  • Certification
  • Community
  • Businesses
  • News
  • Download
  1. Home
  2. Documentation
  3. Routing
  4. How to Match a Route Based on the Host
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud
Search by Algolia

Table of Contents

  • Using Placeholders
  • Using Host Matching of Imported Routes
  • Testing your Controllers

How to Match a Route Based on the Host

Edit this page

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

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

How to Match a Route Based on the Host

You can also match on the HTTP host of the incoming request.

  • Annotations
  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/Acme/DemoBundle/Controller/MainController.php
namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class MainController extends Controller
{
    /**
     * @Route("/", name="mobile_homepage", host="m.example.com")
     */
    public function mobileHomepageAction()
    {
        // ...
    }

    /**
     * @Route("/", name="homepage")
     */
    public function homepageAction()
    {
        // ...
    }
}
1
2
3
4
5
6
7
8
mobile_homepage:
    path:     /
    host:     m.example.com
    defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage }

homepage:
    path:     /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="mobile_homepage" path="/" host="m.example.com">
        <default key="_controller">AcmeDemoBundle:Main:mobileHomepage</default>
    </route>

    <route id="homepage" path="/">
        <default key="_controller">AcmeDemoBundle:Main:homepage</default>
    </route>
</routes>
1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$routes = new RouteCollection();
$routes->add('mobile_homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:mobileHomepage',
), array(), array(), 'm.example.com'));

$routes->add('homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:homepage',
)));

return $routes;

Both routes match the same path /, however the first one will match only if the host is m.example.com.

Using Placeholders

The host option uses the same syntax as the path matching system. This means you can use placeholders in your hostname:

  • Annotations
  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/Acme/DemoBundle/Controller/MainController.php
namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class MainController extends Controller
{
    /**
     * @Route("/", name="projects_homepage", host="{project_name}.example.com")
     */
    public function projectsHomepageAction()
    {
        // ...
    }

    /**
     * @Route("/", name="homepage")
     */
    public function homepageAction()
    {
        // ...
    }
}
1
2
3
4
5
6
7
8
projects_homepage:
    path:     /
    host:     "{project_name}.example.com"
    defaults: { _controller: AcmeDemoBundle:Main:projectsHomepage }

homepage:
    path:     /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="projects_homepage" path="/" host="{project_name}.example.com">
        <default key="_controller">AcmeDemoBundle:Main:projectsHomepage</default>
    </route>

    <route id="homepage" path="/">
        <default key="_controller">AcmeDemoBundle:Main:homepage</default>
    </route>
</routes>
1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$routes = new RouteCollection();
$routes->add('project_homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:projectsHomepage',
), array(), array(), '{project_name}.example.com'));

$routes->add('homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:homepage',
)));

return $routes;

You can also set requirements and default options for these placeholders. For instance, if you want to match both m.example.com and mobile.example.com, you use this:

  • Annotations
  • YAML
  • XML
  • PHP
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
29
30
// src/Acme/DemoBundle/Controller/MainController.php
namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class MainController extends Controller
{
    /**
     * @Route(
     *     "/",
     *     name="mobile_homepage",
     *     host="{subdomain}.example.com",
     *     defaults={"subdomain"="m"},
     *     requirements={"subdomain"="m|mobile"}
     * )
     */
    public function mobileHomepageAction()
    {
        // ...
    }

    /**
     * @Route("/", name="homepage")
     */
    public function homepageAction()
    {
        // ...
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
mobile_homepage:
    path:     /
    host:     "{subdomain}.example.com"
    defaults:
        _controller: AcmeDemoBundle:Main:mobileHomepage
        subdomain: m
    requirements:
        subdomain: m|mobile

homepage:
    path:     /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="mobile_homepage" path="/" host="{subdomain}.example.com">
        <default key="_controller">AcmeDemoBundle:Main:mobileHomepage</default>
        <default key="subdomain">m</default>
        <requirement key="subdomain">m|mobile</requirement>
    </route>

    <route id="homepage" path="/">
        <default key="_controller">AcmeDemoBundle:Main:homepage</default>
    </route>
</routes>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$routes = new RouteCollection();
$routes->add('mobile_homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:mobileHomepage',
    'subdomain'   => 'm',
), array(
    'subdomain' => 'm|mobile',
), array(), '{subdomain}.example.com'));

$routes->add('homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:homepage',
)));

return $routes;

Tip

You can also use service parameters if you do not want to hardcode the hostname:

  • Annotations
  • YAML
  • XML
  • PHP
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
29
30
// src/Acme/DemoBundle/Controller/MainController.php
namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class MainController extends Controller
{
    /**
     * @Route(
     *     "/",
     *     name="mobile_homepage",
     *     host="m.{domain}",
     *     defaults={"domain"="%domain%"},
     *     requirements={"domain"="%domain%"}
     * )
     */
    public function mobileHomepageAction()
    {
        // ...
    }

    /**
     * @Route("/", name="homepage")
     */
    public function homepageAction()
    {
        // ...
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
mobile_homepage:
    path:     /
    host:     "m.{domain}"
    defaults:
        _controller: AcmeDemoBundle:Main:mobileHomepage
        domain: '%domain%'
    requirements:
        domain: '%domain%'

homepage:
    path:  /
    defaults: { _controller: AcmeDemoBundle:Main:homepage }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="mobile_homepage" path="/" host="m.{domain}">
        <default key="_controller">AcmeDemoBundle:Main:mobileHomepage</default>
        <default key="domain">%domain%</default>
        <requirement key="domain">%domain%</requirement>
    </route>

    <route id="homepage" path="/">
        <default key="_controller">AcmeDemoBundle:Main:homepage</default>
    </route>
</routes>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$routes = new RouteCollection();
$routes->add('mobile_homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:mobileHomepage',
    'domain' => '%domain%',
), array(
    'domain' => '%domain%',
), array(), 'm.{domain}'));

$routes->add('homepage', new Route('/', array(
    '_controller' => 'AcmeDemoBundle:Main:homepage',
)));

return $routes;

Tip

Make sure you also include a default option for the domain placeholder, otherwise you need to include a domain value each time you generate a URL using the route.

Using Host Matching of Imported Routes

You can also set the host option on imported routes:

  • Annotations
  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
// src/Acme/HelloBundle/Controller/MainController.php
namespace Acme\HelloBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

/**
 * @Route(host="hello.example.com")
 */
class MainController extends Controller
{
    // ...
}
1
2
3
acme_hello:
    resource: '@AcmeHelloBundle/Resources/config/routing.yml'
    host:     "hello.example.com"
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <import resource="@AcmeHelloBundle/Resources/config/routing.xml" host="hello.example.com" />
</routes>
1
2
3
4
$routes = $loader->import("@AcmeHelloBundle/Resources/config/routing.php");
$routes->setHost('hello.example.com');

return $routes;

The host hello.example.com will be set on each route loaded from the new routing resource.

Testing your Controllers

You need to set the Host HTTP header on your request objects if you want to get past url matching in your functional tests:

1
2
3
4
5
6
7
$crawler = $client->request(
    'GET',
    '/homepage',
    array(),
    array(),
    array('HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain'))
);
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
We stand with Ukraine.
Version:
The life jacket for your team and your project

The life jacket for your team and your project

Measure & Improve Symfony Code Performance

Measure & Improve Symfony Code Performance

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

Avatar of Lars Strojny, a Symfony contributor

Thanks Lars Strojny (@lstrojny) for being a Symfony contributor

23 commits • 800 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