Contributed by
Frank de Jonge
in #26143.

我们最近改进了 路由组件 的性能,令它成为了 PHP最快路由。现在,只需及时把它包容到 Symfony 4.1 中,我们还添加了另一项震撼功能: 支持路由的国际化

这个功能允许根据用户的不同locale来定义不同的路径。此即程序国际化的本质,也是为何诸如 JMSI18nRoutingBundle 的三方bundle拥有百万下载量的原因。在 Symfony 4.1 中我们决定把它整合到路由组件中,以便你可以在 Symfony 程序里直接使用它。

实践中,定义路由之后你可以在 path 选项中提供一个数组来为每一个locale去定义不同的path:

1
2
3
4
5
contact:
    controller: App\Controller\ContactController::send
    path:
        en: /send-us-an-email
        nl: /stuur-ons-een-email

此种格式也被定义在 XML 和 PHP annotations 中的路由所支持:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use Symfony\Component\Routing\Annotation\Route;
 
class ContactController
{
    /**
     * @Route({
     *     "en": "/send-us-an-email",
     *     "nl": "/stuur-ons-een-email"
     * }, name="contact")
     */
    public function send()
    {
        // ...
    }
}

Symfony 在内部为每一个 locale 都创建了一个路由(本例中,名为 contact.encontact.nl),但是你可以使用原始的路由名称来生成URLs。在生成链接时,请求中的 locale 被默认使用,但你也可以显式传入 locale 以生成任意可选的链接:

1
2
3
4
5
6
7
8
9
10
11
/** @var UrlGeneratorInterface $urlGenerator */
// uses the current request locale
// 使用当前请求中的 locale
$url = $urlGenerator->generate('contact');
 
// ignores the current request locale and generates '/stuur-ons-een-email'
// 忽略当前请求中的 locale,而是生成  '/stuur-ons-een-email'
$url = $urlGenerator->generate('contact', ['_locale' => 'nl']);
// this would also work, but it's not recommended:
// 仍可运行,但并不推荐
// $url = $urlGenerator->generate('contact.nl');

路由前缀也是可以被翻译的 (YAML/XML 文件和controller中的类级 @Route annotations 都是可以的),你也可以混合已翻译和未翻译的path:

1
2
3
4
5
6
# config/routes/annotations.yaml
site:
    resource: '../src/Controller/'
    type: annotation
    prefix:
        en: '/site'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class DefaultController extends Controller
{
    /**
     * @Route({"en": "/contact", "es": "/contacto"}, name="contact")
     */
    public function contact()
    {
        // ...
    }
 
    /**
     * @Route("/page/{slug}", name="page")
     */
    public function page($slug)
    {
        // ...
    }
}

针对以上,Symfony 所生成的四种路由分别是:

Route name Route path
contact.en /site/contact
contact.es /sitio/contacto
page.en /site/page/{slug}
page.es /sitio/page/{slug}