Как сделать так, чтобы маршрут соответствовал на основании хоста

Как сделать так, чтобы маршрут соответствовал на основании хоста

Вы также можете сделатьтак, чтобы маршрут соответствовал на HTTP хосте входящего запроса.

  • Annotations
     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/AppBundle/Controller/MainController.php
    namespace AppBundle\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()
        {
            // ...
        }
    }
    
  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    mobile_homepage:
        path:     /
        host:     m.example.com
        defaults: { _controller: AppBundle:Main:mobileHomepage }
    
    homepage:
        path:     /
        defaults: { _controller: AppBundle:Main:homepage }
    
  • XML
     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">AppBundle:Main:mobileHomepage</default>
        </route>
    
        <route id="homepage" path="/">
            <default key="_controller">AppBundle:Main:homepage</default>
        </route>
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('mobile_homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:mobileHomepage',
    ), array(), array(), 'm.example.com'));
    
    $collection->add('homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:homepage',
    )));
    
    return $collection;
    

Оба маршрута соответствуют одинакому пути /, однако первый будет соответствовать только, если хост будет m.example.com.

Использование заполнителей

Опция хоста использует тот же синтаксис, что и система соответствия путей. Это означает, что вы можете использовать заполнители в имени вашего хоста:

  • Annotations
     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/AppBundle/Controller/MainController.php
    namespace AppBundle\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()
        {
            // ...
        }
    }
    
  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    projects_homepage:
        path:     /
        host:     "{project_name}.example.com"
        defaults: { _controller: AppBundle:Main:projectsHomepage }
    
    homepage:
        path:     /
        defaults: { _controller: AppBundle:Main:homepage }
    
  • XML
     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">AppBundle:Main:projectsHomepage</default>
        </route>
    
        <route id="homepage" path="/">
            <default key="_controller">AppBundle:Main:homepage</default>
        </route>
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('project_homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:projectsHomepage',
    ), array(), array(), '{project_name}.example.com'));
    
    $collection->add('homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:homepage',
    )));
    
    return $collection;
    

Вы также можете установить условия и опции по умолчанию для этих заполнителей. Например, если вы хотите, чтобы соответствовал и m.example.com и mobile.example.com, вы будете использовать следующее:

  • Annotations
     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/AppBundle/Controller/MainController.php
    namespace AppBundle\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()
        {
            // ...
        }
    }
    
  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    mobile_homepage:
        path:     /
        host:     "{subdomain}.example.com"
        defaults:
            _controller: AppBundle:Main:mobileHomepage
            subdomain: m
        requirements:
            subdomain: m|mobile
    
    homepage:
        path:     /
        defaults: { _controller: AppBundle:Main:homepage }
    
  • XML
     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">AppBundle:Main:mobileHomepage</default>
            <default key="subdomain">m</default>
            <requirement key="subdomain">m|mobile</requirement>
        </route>
    
        <route id="homepage" path="/">
            <default key="_controller">AppBundle:Main:homepage</default>
        </route>
    </routes>
    
  • PHP
     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;
    
    $collection = new RouteCollection();
    $collection->add('mobile_homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:mobileHomepage',
        'subdomain'   => 'm',
    ), array(
        'subdomain' => 'm|mobile',
    ), array(), '{subdomain}.example.com'));
    
    $collection->add('homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:homepage',
    )));
    
    return $collection;
    

Tip

Вы также можете использовать параметры сервиса, если вы не хотите жестко кодировать имя хоста:

  • Annotations
     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/AppBundle/Controller/MainController.php
    namespace AppBundle\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()
        {
            // ...
        }
    }
    
  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    mobile_homepage:
        path:     /
        host:     "m.{domain}"
        defaults:
            _controller: AppBundle:Main:mobileHomepage
            domain: '%domain%'
        requirements:
            domain: '%domain%'
    
    homepage:
        path:  /
        defaults: { _controller: AppBundle:Main:homepage }
    
  • XML
     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">AppBundle:Main:mobileHomepage</default>
            <default key="domain">%domain%</default>
            <requirement key="domain">%domain%</requirement>
        </route>
    
        <route id="homepage" path="/">
            <default key="_controller">AppBundle:Main:homepage</default>
        </route>
    </routes>
    
  • PHP
     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;
    
    $collection = new RouteCollection();
    $collection->add('mobile_homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:mobileHomepage',
        'domain' => '%domain%',
    ), array(
        'domain' => '%domain%',
    ), array(), 'm.{domain}'));
    
    $collection->add('homepage', new Route('/', array(
        '_controller' => 'AppBundle:Main:homepage',
    )));
    
    return $collection;
    

Tip

Убедитесь в том, что вы также включаете опцию по умолчанию для заполнителя domain, иначе вам понадобится включать значение домена каждый раз, когда вы будете генерировать URL используя маршрут.

Использование соответствия хостов в импортированных маршрутах

Вы также можете установить опцию хоста в импортированных маршрутах:

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    // src/AppBundle/Controller/MainController.php
    namespace AppBundle\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    
    /**
     * @Route(host="hello.example.com")
     */
    class MainController extends Controller
    {
        // ...
    }
    
  • YAML
    1
    2
    3
    app_hello:
        resource: '@AppBundle/Resources/config/routing.yml'
        host:     "hello.example.com"
    
  • XML
    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="@AppBundle/Resources/config/routing.xml" host="hello.example.com" />
    </routes>
    
  • PHP
    1
    2
    3
    4
    $collection = $loader->import("@AppBundle/Resources/config/routing.php");
    $collection->setHost('hello.example.com');
    
    return $collection;
    

Хост hello.example.com будет установлен на каждом маршруте, загружаемом из нового ресурса маршрутизации.

Тестирование ваших контроллеров

Вам нужно установить HTTP-заголовок хоста в ваших объектах запроса, если вы хотите продвинуться в ваших тестах дальше, чем соответствие URL.

1
2
3
4
5
6
7
$crawler = $client->request(
    'GET',
    '/homepage',
    array(),
    array(),
    array('HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain'))
);

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.