Symfony国际化需在config/packages/framework.yaml中配置framework.translator,设default_locale为兜底值、locales为语言白名单,翻译文件按domain.locale.format命名并置于translations/目录,调用trans()时确保locale在白名单且domain匹配。
Symfony 的国际化(i18n)和
本地化
(l10n)不是“开箱即用”的魔法开关,而是靠明确配置、约定路径和正确调用翻译服务来驱动的。默认只启用英文,其他语言必须显式声明并提供翻译资源,否则
会原样返回源字符串。
如何在 config/packages/framework.yaml 中启用多语言支持
Symfony 的翻译能力由
配置控制,不写这一段就等于没开翻译功能。关键点是:
决定 fallback 行为,
列表才是真正允许切换的语言白名单。
常见错误是只改了
却漏掉
,结果
能读到 fr,但
仍走 en 翻译——因为 fr 不在白名单里,框架直接忽略。
是兜底值,不是“默认生效语言”,仅当请求未指定 locale 或 locale 不在白名单时才起作用
必须列出所有你打算支持的语言代码,大小写敏感(
无效,得写
)
如果项目用 Twig 模板,确保
下的
或 CDN 配置不影响静态资源路径,否则翻译文件加载可能 404
翻译文件该放在哪?命名和格式怎么写才被识别
Symfony 默认按
或
查找,但最常用且推荐的是 XLIFF 格式,路径必须严格匹配约定:
→ 法语翻译
→ 简体中文翻译
→ 仅用于验证器错误信息的英文翻译
容易踩的坑:
文件名中的
是 domain,默认 domain 就是
;如果代码里写
,就得放
XLIFF 文件里
标签内容不能为空,否则 Symfony 会跳过该条目,静默回退到源字符串
不要手动编辑
或
文件——Symfony 不读它们;
是另一套体系,和 Symfony Translator 组件互不兼容
如何动态切换当前请求的 locale
locale 不是全局变量,它绑定在每个 Request 上。不能靠
或环境变量修改,必须通过 Request 对象或路由参数注入。
本地化jQuery公式加中文键盘
本地化jQuery公式加中文键盘
下载
最可靠的方式是把 locale 当作路由前缀:
然后在控制器里用
读取,或直接作为参数注入:
注意:
别在中间件或事件监听器里硬编码
—— Symfony 10+ 已移除该方法,会报
Session 或 Cookie 存的 locale 值,必须在每次请求开始时通过
显式设置到 request 上,否则
仍用默认 locale
使用
跳转时,记得带上当前 locale 参数,否则用户切语言后点链接又跳回默认语言
为什么 trans() 返回原文而不是翻译?排查三步法
这是最常遇到的问题,本质是“翻译链断了”。按顺序检查:
看日志:启用
模式后,
事件会记录未找到的 key,grep
里的
确认 locale 是否在
的
列表中,且与文件名后缀完全一致(包括下划线)
运行
(替换为你实际的 locale),它会列出所有已加载的 translation key 及状态(missing / unused),比手动翻文件快得多
真正麻烦的不是找不到翻译,而是翻译存在却因 domain 错误、缓存未清除或 ICU 格式语法错误(比如
缺少闭合括号)被静默忽略——这种问题不会报错,只会默默返回原文。
trans()framework.translatordefault_localelocalesdefault_localelocalesapp.request.localetrans()default_locale: 'en'locales: ['en', 'fr', 'zh_CN', 'ja']zh-cnzh_CNframework.assetsbase_urlstranslations/messages+intl-icu.{locale}.xlfmessages.{locale}.phptranslations/messages.fr.xlftranslations/messages.zh_CN.xlftranslations/validators.en.xlfmessagesmessages$translator->trans('key', [], 'admin')translations/admin.fr.xlf.mo.pogettextsetlocale()framework:
router:
strict_requirements: null
# config/routes.yaml
controllers:
resource: ../../src/Controller/
type: annotation
prefix: /{_locale}
requirements: {_locale: '%supported_locales%'}
$request->getLocale()public function index(Request $request, string $_locale): Response
{
// $_locale 已自动解析为路由参数,如 /fr/xxx → $_locale === 'fr'
}
$request->setLocale('fr')BadMethodCallExceptionRequestEventtrans()RedirectResponsedebugtranslator.missing_translationvar/log/dev.logTranslation not foundframework.yamllocalesbin/console debug:translation fr{count, plural, =0{...}}