翻译缓存没生效需先确认是否正确配置cache.translation池,symfony 7默认不继承cache.app设置,须在translation.yaml中显式指定redis适配器并确保provider已定义;开发环境该缓存默认禁用,仅prod生效。

翻译缓存没生效?先确认是否用了正确的缓存池
Symfony 7 的翻译系统默认使用 cache.translation 池,但它不会自动继承你为 cache.app 配置的 Redis 或其他后端——除非你显式覆盖。常见错误是改了 cache.app 用 Redis,却忘了同步配置翻译池,结果翻译仍写入文件缓存,IO 成瓶颈。
正确做法是在 config/packages/translation.yaml 中明确指定:
framework:
translator:
cache: 'cache.translation'
cache:
pools:
cache.translation:
adapter: cache.adapter.redis_tag_aware
provider: cache.default_redis_provider
注意:cache.adapter.redis_tag_aware 支持按 domain / locale 批量失效,比普通 Redis adapter 更适合翻译场景;若用 cache.adapter.redis,locale 切换后旧翻译不会自动清理。
- 必须确保
cache.default_redis_provider已在cache.yaml中正确定义且 Redis 可连通 - 执行
php bin/console cache:clear --env=prod后,检查var/cache/prod/pools/cache.translation/是否为空——非空说明还在走文件缓存 - 开发环境(
APP_ENV=dev)下cache.translation默认禁用,仅在prod下生效
翻译加载慢,大概率是 catalog 编译没预热
Symfony 7 把翻译消息编译成 PHP 数组(如 messages+intl-icu.en.php),这个过程发生在首次请求或缓存未命中时。若没预热,首屏加载可能卡顿 200–500ms,尤其当项目有几十个 domain + 多语言时。
关键动作不是等它自动编译,而是主动触发:
php bin/console translation:extract --config=app --force --output-format=php --no-interaction php bin/console cache:warmup --env=prod
这两步必须一起跑:translation:extract 确保最新消息写入 translations/ 目录;cache:warmup 才会把它们真正编译进 var/cache/prod/translations/。
- 跳过
--force可能漏掉新添加的 key,导致运行时报Missing message - 不要只清
cache:clear—— 它不重建翻译 catalog,必须cache:warmup - CI/CD 部署脚本里漏掉这一步,上线后第一个用户就承担编译开销
翻译上下文(context)滥用导致缓存碎片化
当你用 $translator->trans('key', [], 'domain', 'fr', ['context' => 'admin']),Symfony 会为每个唯一 context 生成独立 catalog 文件。大量动态 context(比如拼接用户 ID、时间戳)会让缓存键爆炸式增长,命中率暴跌。
真实案例:某后台用 context 区分权限级别(context: user_role_123),结果每用户一个缓存文件,Redis 内存涨了 3 倍,且几乎无复用。
- context 应仅用于语义差异明确的静态分类(如
email/ui/error),而非动态标识 - 动态逻辑尽量移到模板或业务层处理,例如用不同 key:
user.profile.edit.adminvsuser.profile.edit.user - 检查
var/cache/prod/translations/下文件数量:超过 200 个 .php 文件,大概率存在 context 泛滥
Twig 中 trans 过滤器没走缓存?检查是否用了变量 key
{{ 'welcome'|trans }} 走缓存,但 {{ someKey|trans }} 不走——因为 Symfony 在 Twig 编译阶段无法静态分析变量值,只能运行时解析,绕过所有预编译 catalog。
这种写法在 debug 模式下可能不报错,但生产环境会退化成逐条查 YAML/PHP 文件,CPU 和 IO 双飙升。
- 禁止在
|trans左侧传变量;必须用字面量字符串或常量 - 动态 key 场景改用
transchoice或提前在控制器中 resolve:$message = $translator->trans($dynamicKey),再传给模板 - 用 Blackfire 或 Xdebug profile 对比:
|trans变量调用的MessageCatalogue::get调用次数会远高于字面量
翻译缓存最易被忽略的点:它不依赖 APP_DEBUG 开关,而严格绑定 APP_ENV。哪怕你 APP_DEBUG=true 但 APP_ENV=prod,翻译依然走预编译缓存;反过来,APP_ENV=dev 下无论怎么配 Redis,它都强制走 runtime 解析——这点和 HTTP 缓存、容器缓存的行为逻辑完全不同。











