如何在路由中使用服务容器的参数

3.4 版本
维护中的版本

有时,你可能会发现令你的路由中某些部分“全局可配置”是有用的。例如,如果你构建一个国际化的网站,你会从一两个地方开始。当然,你需要添加一个条件(requirements)到你的路由,以防止用户匹配到其他地区而不是你所支持地区的语言。

你很可能会在路由中写死_locale条件,但一个更好的方案是在你的路由配置中,使用一个可配置的服务容器参数:

1
2
3
4
5
6
# app/config/routing.yml
contact:
    path:     /{_locale}/contact
    defaults: { _controller: AppBundle:Main:contact }
    requirements:
        _locale: '%app.locales%'
1
2
3
4
5
6
7
8
9
10
11
<!-- app/config/routing.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="contact" path="/{_locale}/contact">
        <default key="_controller">AppBundle:Main:contact</default>
        <requirement key="_locale">%app.locales%</requirement>
    </route>
</routes>
1
2
3
4
5
6
7
8
9
10
11
12
// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
 
$collection = new RouteCollection();
$collection->add('contact', new Route('/{_locale}/contact', array(
    '_controller' => 'AppBundle:Main:contact',
), array(
    '_locale' => '%app.locales%',
)));
 
return $collection;

现在你可以在容器中的某个位置来控制并设置 app.locales 参数:

1
2
3
# app/config/config.yml
parameters:
    app.locales: en|es
1
2
3
4
<!-- app/config/config.xml -->
<parameters>
    <parameter key="app.locales">en|es</parameter>
</parameters>
1
2
// app/config/config.php
$container->setParameter('app.locales', 'en|es');

你还可以使用参数来定义路由的路径(或者路径的一部分):

1
2
3
4
# app/config/routing.yml
some_route:
    path:     /%app.route_prefix%/contact
    defaults: { _controller: AppBundle:Main:contact }
1
2
3
4
5
6
7
8
9
10
<!-- app/config/routing.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="some_route" path="/%app.route_prefix%/contact">
        <default key="_controller">AppBundle:Main:contact</default>
    </route>
</routes>
1
2
3
4
5
6
7
8
9
10
// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
 
$collection = new RouteCollection();
$collection->add('some_route', new Route('/%app.route_prefix%/contact', array(
    '_controller' => 'AppBundle:Main:contact',
)));
 
return $collection;

就像在一般的容器配置文件中一样,如果你真的需要在路由中使用%,你可以通过使用两个%来令其转义,如/score-50%%,它会被处理为 /score-50%

然而,任何含有%的字符的URL都会自动地被encoded,本例的URL最终将会是/score-50%25(这个%25就是%字符encoding之后的结果)。

关于在依赖注入类(Dependency Injection Class)内部的参数处理,参考 在依赖注入类内部使用参数

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)