Как позволить знак "/" в параметре маршрута

Иногда вам может понадобиться составить URL с парамерами, которые могут содержать слеш /. Например, рассмотрите маршрут /share/{token}. Если значение token содержит символ /, то этот маршрут не будет совпадать. Это так, потому что Symfony использует этот символ в качестве разделителя между частями маршрута.

Эта статья объясняет, как вы можете изменить определение маршрута, чтобы заполнители тоже могли содержать символ /.

Сконфигурируйте маршрут

По умолчанию, компонент Symfony Маршрутизация требует, чтобы параметры совпадали со следующим регулярным выражением: [^/]+. Это означает, что разрешены все символы, кроме /.

Вы дожны ясно позволить / быть частью вашего заполнителя, указав более ползволительное регулярное выражение для этого:

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    use Symfony\Component\Routing\Annotation\Route;
    
    class DefaultController
    {
        /**
         * @Route("/share/{token}", name="share", requirements={"token"=".+"})
         */
        public function share($token)
        {
            // ...
        }
    }
    
  • YAML
    1
    2
    3
    4
    5
    6
    # config/routes.yaml
    share:
        path:       /share/{token}
        controller: App\Controller\DefaultController::share
        requirements:
            token: .+
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    <!-- config/routes.xml -->
    <?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="share" path="/share/{token}">
            <default key="_controller">App\Controller\DefaultController::share</default>
            <requirement key="token">.+</requirement>
        </route>
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    // config/routes.php
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('share', new Route('/share/{token}', array(
        '_controller' => 'App\Controller\DefaultController::share',
    ), array(
        'token' => '.+',
    )));
    
    return $collection;
    

Вот и всё! Теперь параметр {token} может содержать символ /.

Note

Если маршрут включает в себя особенный заполнитель {_format}, то вам не стоит использовать требование .+ для параметров, позволяющих слеши. Например, если шаблон /share/{token}.{_format}, а {token} позволяет любые символы, то URL /share/foo/bar.json будет рассматривать foo/bar.json, как токен, и формат будет пустым. Это можно решить, заменив требование .+ на [^.]+, чтобы позволить любые символы, кроме точек.

Note

Если маршрут определяет несколько заполнителей, и вы применяете это позволительное регулярное выражение ко всем из них, то результаты не будут ожидаемы. Например, если определение маршрута - /share/{path}/{token}, а path и token принимают /, то path будет содержать своё содержимое и токен, а token будет пустым.

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