symfony - 使用自定义侦听器设置的区域设置被覆盖
问题描述
我的意图是根据 Accept-Language HTTP 请求标头设置语言环境。
我已经创建了自定义 LocaleListener 类,并在 config/services.yaml 中将其配置为优先级高于 LocaleListener,如下所示:https ://symfony.com/doc/current/translation/locale.html
该onKernelRequest()
方法中包含的逻辑成功地检索了我传递给该setLocale()
方法的语言环境。
在同一文件中回显当前语言环境会返回预期的语言环境(由用户浏览器定义的语言环境)。但是,最终,此语言环境被覆盖,更改为应用程序默认值。
这就是问题所在。我需要确定覆盖区域设置的内容以及可能的解决方案。Symfony 文档并没有那么深入。我打算用我发现的内容为文档做出贡献。
这是一个运行在 GNU/Linux 上的 Symfony 4 应用程序。
我收集了以下输出php bin/console debug:event kernel.request
:
Registered Listeners for "kernel.request" Event
===============================================
------- ------------------------------------------------------------------------------------------------- ----------
Order Callable Priority
------- ------------------------------------------------------------------------------------------------- ----------
#1 Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure() 2048
#2 Symfony\Component\HttpKernel\EventListener\ValidateRequestListener::onKernelRequest() 256
#3 Symfony\Component\HttpKernel\EventListener\SessionListener::onKernelRequest() 128
#4 App\EventListener\LocaleListener::onKernelRequest() 110
#5 Symfony\Component\HttpKernel\EventListener\LocaleListener::setDefaultLocale() 100
#6 Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest() 32
#7 Symfony\Bundle\FrameworkBundle\EventListener\ResolveControllerNameSubscriber::onKernelRequest() 24
#8 Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest() 16
#9 Symfony\Component\HttpKernel\EventListener\LocaleAwareListener::onKernelRequest() 15
#10 Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::configureLogoutUrlGenerator() 8
#11 Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::onKernelRequest() 8
------- ------------------------------------------------------------------------------------------------- ----------
如您所见,在所有其他与语言环境相关的侦听器之上,有我的自定义侦听器。
我试图设置它的优先级,所以它在 setDefaultLocale() 之后执行,但最终语言环境仍然是默认值,'en'。
这是来自 src/EventListener/ 的自定义监听器代码:
<?php
namespace App\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
class LocaleListener
{
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
// LOGIC TO RETRIEVE LOCALE
$request->setLocale($locale);
}
}
观察 01:$locale 变量在回显时返回预期的字符串。
观察 02:在上述方法中回显 $request->getLocale() 返回预期的字符串,这意味着此时区域设置已成功更改。
以下是 config/services.yaml 底部的监听器配置
App\EventListener\LocaleListener:
tags:
- { name: kernel.event_listener, event: kernel.request, priority: 110 }
预计语言环境将根据浏览器上定义的语言进行更改 - 第一个是“pt”葡萄牙语;但是,语言环境继续设置为默认值“en”。
解决方案
是路由器。
路由器配置为在所有路由上使用前缀,这决定了语言环境,例如 /pt 或 /en。我只需要禁用它们,然后应用程序将根据我的浏览器语言环境成功确定语言环境。
现在我只需要弄清楚如何保持区域设置前缀可用,同时仍然主要使用 Accept-Language 信息。然后前缀将充当此自动定义的语言环境的覆盖。这就是许多流行网站的工作方式,尽管通过单个 URL 提供不同内容并不是最佳实践。
推荐阅读
- c++ - vscode调试同一文件夹中的多个文件
- r - [R Shiny]:如何在 R Shiny 应用程序中按 x 轴上的时间范围过滤并同时在 y 轴上具有两个不同的变量
- ruby - 是否可以从带有 String 的模块执行方法?- 红宝石 2.7.1
- java - 对可序列化对象使用泛化
- html - 如何使用css在框内使用变换比例缩放图像
- mongodb - 更新文档 mongodb (v4) 中的部分列表
- angular - 如何在 Angular 库对等依赖项中注入 HttpClient?
- javascript - 如何在桌面上调试 WebSocket / 服务器发送事件重新连接?
- docker - 无法验证“docker”驱动程序(kubernetes)
- c - 初始化结构数组成员的最有效方法?