根本原因是Translator未同步请求locale,需确保路由配置{_locale}前缀、LocaleAwareListener启用、session开启,并验证$request->get('_locale')和$translator->getLocale()是否一致。

切换语言后 trans() 仍返回旧语言内容,根本原因不是翻译文件没写对,而是 Symfony 的 Translator 实例没有同步当前请求的 locale。它默认依赖 request_stack 获取 locale,但前提是这个 locale 已被正确设置到 HTTP 请求中。
确认路由已启用 locale 前缀并传递参数
URL 中的 /fr/news 不会自动生效,必须显式配置路由支持 _locale 参数:
- 检查
config/routes.yaml是否包含带{_locale}的前缀,例如:controllers:<br> resource: ../src/Controller/<br> type: annotation<br> prefix: '/{_locale}'<br> defaults: { _locale: '%kernel.default_locale%' } - 确保控制器方法或路由注解中未硬编码 locale,比如
@Route("/news", name="news")会丢失_locale;应改用@Route("/{_locale}/news", name="news", requirements={"_locale"="en|fr|es"})
验证 locale 是否真正注入到 Request 对象
即使 URL 包含 _locale,若中间件或监听器未触发,request 里依然拿不到值:
- 在控制器中打印:
dump($this->getRequest()->get('_locale'));看是否输出预期语言(如fr) - 若为
null或默认值(如en),说明LocaleAwareListener没运行——它依赖 session 服务,需确认config/packages/framework.yaml中启用了session配置 - 检查
framework.session.enabled是否为true;禁用 session 会导致 locale 无法持久化和传递
检查 translator 是否使用了动态 locale
Translator 默认读取 request 的 locale,但前提是它被正确绑定:
- 调试时执行:
dump($translator->getLocale());—— 若始终是en,说明 locale 未更新 - 确认
config/packages/framework.yaml中default_locale没被环境变量覆盖(例如APP_DEFAULT_LOCALE=zh在 .env 中未设置) - Twig 模板中避免直接用
{{ app.request.get('_locale') | trans }},应由控制器解析后传入变量,再调用{{ 'hello'|trans({}, 'messages', current_locale) }}
确保 translation 配置允许动态加载
路径和格式错误会导致翻译资源压根没加载,locale 再准也白搭:
- 确认
config/packages/translation.yaml含default_path: '%kernel.project_dir%/translations',且该目录存在、可读 - 文件命名必须严格为
messages.fr.xlf(非.yaml),Symfony 6+ 默认不加载 YAML 翻译文件 - 若用了自定义域(如
admin.fr.xlf),调用时必须指定domain: 'admin',否则仍查messages域











