.. index:: single: Routing; Matching on Hostname How to Match a Route Based on the Host ====================================== .. versionadded:: 2.2 Host matching support was introduced in Symfony 2.2 You can also match on the HTTP *host* of the incoming request. .. configuration-block:: .. code-block:: yaml mobile_homepage: path: / host: m.example.com defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage } homepage: path: / defaults: { _controller: AcmeDemoBundle:Main:homepage } .. code-block:: xml AcmeDemoBundle:Main:mobileHomepage AcmeDemoBundle:Main:homepage .. code-block:: php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('mobile_homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:mobileHomepage', ), array(), array(), 'm.example.com')); $collection->add('homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:homepage', ))); return $collection; 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: .. configuration-block:: .. code-block:: yaml projects_homepage: path: / host: "{project_name}.example.com" defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage } homepage: path: / defaults: { _controller: AcmeDemoBundle:Main:homepage } .. code-block:: xml AcmeDemoBundle:Main:mobileHomepage AcmeDemoBundle:Main:homepage .. code-block:: php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('project_homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:mobileHomepage', ), array(), array(), '{project_name}.example.com')); $collection->add('homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:homepage', ))); return $collection; 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: .. configuration-block:: .. code-block:: yaml 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 } .. code-block:: xml AcmeDemoBundle:Main:mobileHomepage m m|mobile AcmeDemoBundle:Main:homepage .. code-block:: php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('mobile_homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:mobileHomepage', 'subdomain' => 'm', ), array( 'subdomain' => 'm|mobile', ), array(), '{subdomain}.example.com')); $collection->add('homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:homepage', ))); return $collection; .. tip:: You can also use service parameters if you do not want to hardcode the hostname: .. configuration-block:: .. code-block:: yaml mobile_homepage: path: / host: "m.{domain}" defaults: _controller: AcmeDemoBundle:Main:mobileHomepage domain: "%domain%" requirements: domain: "%domain%" homepage: path: / defaults: { _controller: AcmeDemoBundle:Main:homepage } .. code-block:: xml AcmeDemoBundle:Main:mobileHomepage %domain% %domain% AcmeDemoBundle:Main:homepage .. code-block:: php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('mobile_homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:mobileHomepage', 'domain' => '%domain%', ), array( 'domain' => '%domain%', ), array(), 'm.{domain}')); $collection->add('homepage', new Route('/', array( '_controller' => 'AcmeDemoBundle:Main:homepage', ))); return $collection; .. 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. .. _component-routing-host-imported: Using Host Matching of Imported Routes -------------------------------------- You can also set the host option on imported routes: .. configuration-block:: .. code-block:: yaml # app/config/routing.yml acme_hello: resource: "@AcmeHelloBundle/Resources/config/routing.yml" host: "hello.example.com" .. code-block:: xml .. code-block:: php // app/config/routing.php use Symfony\Component\Routing\RouteCollection; $collection = new RouteCollection(); $collection->addCollection($loader->import("@AcmeHelloBundle/Resources/config/routing.php"), '', array(), array(), array(), 'hello.example.com'); return $collection; 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. .. code-block:: php $crawler = $client->request( 'GET', '/homepage', array(), array(), array('HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain')) );