支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
当前用户的locale被存在请求中,可以通过 Request
对象访问到:
1 2 3 4 5 6 | use Symfony\Component\HttpFoundation\Request;
public function indexAction(Request $request)
{
$locale = $request->getLocale();
} |
要设置用户的locale,你可能希望创建一个自定义的事件监听,以便它在系统的其他部分(比如translator)需要它之前就被设置好:
1 2 3 4 5 6 7 | public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
// some logic to determine the $locale
$request->setLocale($locale);
} |
参考 把locale信息“粘连”到用户的Session周期中 以了解更多内容。
在控制器中使用 $request->setLocale()
来设置locale以便左右translator实在是太迟了。可以通过监听 (如上), URL (见下文) 或是直接对 translator
服务来调用 setLocale()
。
下文的 Locale 和 URL 小节有讲到通过路由来设置locale。
由于你可以把locale存到用户的session中,根据用户的locale,它可能会尝试使用相同的URL来显示不同语言的资源。例如,http://www.example.com/contact
可以对某个用户显示英语内容,但对另一个用户有显示法语的。不幸的是,这会粗暴破坏互联网的一个基本原则:即,特定的URL要对用户返回相同的资源,不管是什么(语种的)用户。进一步搞砸问题的是,哪个版本的内容可以被搜索引擎检索到?
一个很好的策略是,把locale包容到URL之中。通过使用一个特殊的 _locale
参数(parameter),该策略已为路由系统完整支持:
1 2 3 4 5 6 | # app/config/routing.yml
contact:
path: /{_locale}/contact
defaults: { _controller: AppBundle:Contact:index }
requirements:
_locale: en|fr|de |
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- 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:Contact:index</default>
<requirement key="_locale">en|fr|de</requirement>
</route>
</routes> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 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:Contact:index',
),
array(
'_locale' => 'en|fr|de',
)
));
return $collection; |
当使用特殊的 _locale
路由参数时,匹配到的locale将 自动设置到Request对象中 然后可以透过 getLocale()
方法来取出。换言之,如果一个用户访问的URI是 /fr/contact
,那么locale fr
将自动地被设置为当前请求的locale。
现在你可以使用locale来创建路由,用于程序中的其他需要翻译的页面。
参考 如何在路由中使用服务容器的参数 来了解如何避免在全部路由中写死 _locale
条件(requirement)。
若无法确定用户的locale怎么办?在框架中配置好 default_locale
,即可确保用户在每一次请求中皆已被设置locale:
1 2 3 | # app/config/config.yml
framework:
default_locale: en |
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config default-locale="en" />
</container> |
1 2 3 4 | // app/config/config.php
$container->loadFromExtension('framework', array(
'default_locale' => 'en',
)); |
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。