You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 6(PHP8) XLIFF复数翻译存在对应键时功能异常问题

问题根因

Symfony 翻译组件对XLIFF格式文件的复数解析逻辑和原生字符串回退逻辑不一致:

  • 当.xlf文件里找不到对应翻译键时,组件直接读取Twig中传入的原始带|分隔的复数字符串,内置解析器会自动拆分区间规则,按传入的%count%匹配对应分支,此时功能正常。
  • 当.xlf文件中存在匹配的翻译条目时,XLIFF加载器默认将单个<trans-unit>下的<target>内容识别为普通单条翻译文本,不会自动解析你写在target里的|分隔复数分支,直接把整段文本返回,导致复数规则失效。调试面板显示的“复数功能正常”仅代表检测到传入了%count%参数,不代表当前翻译条目被正确识别为复数单元。

你当前的XLIFF写法本身不符合Symfony XLIFF驱动的复数识别规则——直接把区间式复数串放在单个target节点的简写,仅在YAML、PHP翻译文件、模板原生回退场景下生效,XLIFF格式不支持这种写法。

修复方案

方案1:按XLIFF 1.2规范声明复数节点

在target节点内添加标准PLURAL标识节点,显式告知加载器当前条目为复数翻译,示例配置:

<trans-unit id="Y9p7sja1" resname="item_found_count">
    <source>item_found_count</source>
    <target>
        <x id="PLURAL" equiv-text="%count%"/>
        {0}Any item found1|{1}One item found2|]1,Inf[ Found %count% items3
    </target>
</trans-unit>

对应Twig调用修改为使用自定义键名:

{{ "item_found_count" | trans({'%count%': paginated_data.totalItemCount}) }}

XLIFF加载器只有检测到target内存在<x id="PLURAL" equiv-text="%count%"/>节点时,才会触发复数拆分逻辑。
注意:不要把带|和区间标记的完整长字符串作为resname/source值,这类长键会强制触发普通文本匹配逻辑,跳过复数解析。

方案2:使用ICU消息格式(推荐,Symfony 6原生适配)

ICU格式是Symfony 6推荐的翻译格式,跨文件格式兼容性好,不需要额外节点标识,XLIFF配置示例:

<trans-unit id="Y9p7sja1" resname="item_found_count">
    <source>item_found_count</source>
    <target>{count, plural,
        =0 {Any item found1}
        =1 {One item found2}
        other {Found # items3}
    }</target>
</trans-unit>

对应Twig调用:

{{ "item_found_count" | trans({'count': paginated_data.totalItemCount}) }}

使用ICU格式时注意:计数参数不需要加%包裹,规则内的#会自动替换为传入的计数值,多语言复数规则适配更简单,不会出现格式兼容问题。

临时规避方案(不推荐生产使用)

如果暂时不想调整XLIFF结构,可以将对应翻译文件命名为带+intl-icu后缀的格式(比如messages+intl-icu.zh_CN.xlf),但这种方式对直接写在target里的|分隔复数分支兼容性不稳定,仅适合临时调试使用。


内容的提问来源于stack exchange,提问作者Dmitriy.Net

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:54:20