Symfony 翻译 组件提供了能够让你的PHP程序国际化的工具。工具之一是 transChoice() 方法,可以选择一个基于某数字的翻译,正好解决了(翻译时的)复数化的问题(pluralization)。

可是,该方法使用了一个优先级格式来定义翻译,并不允许去选择那些基于其他条件的翻译信息(如,基于某个人的性别)。

同时,由 ICU project 所创建的 MessageFormat(翻译信息之格式)已是一个应用在大量程序中的标准,支持更多功能。这也是为何 Symfony 4.2 引入了一个 IntlFormatter 类,来作为 transChoice() 的替代者。

full MessageFormat format guide 因其所支持的全部功能,在一开始可能会比较难。下例在选择翻译信息时依据的是性别,以及一个数字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use Symfony\Component\Translation\Formatter\IntlFormatter;
 
$translation = <<<'_TRANSLATION_'
{gender_of_host, select,
  female {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to her party.}
      =2 {{host} invites {guest} and one other person to her party.}
     other {{host} invites {guest} as one of the # people invited to her party.}}}
  male   {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to his party.}
      =2 {{host} invites {guest} and one other person to his party.}
     other {{host} invites {guest} as one of the # people invited to his party.}}}
  other {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to their party.}
      =2 {{host} invites {guest} and one other person to their party.}
     other {{host} invites {guest} as one of the # people invited to their party.}}}}
_TRANSLATION_;
 
$message = (new IntlFormatter())->formatIntl($translation, 'en', [
    'gender_of_host' => 'male',
    'num_guests' => 10,
    'host' => 'Jon',
    'guest' => 'Jane',
]);
// $message = 'Jon invites Jane as one of the 9 people invited to his party.'

在 Symfony 程序中,这个新的格式化工具基于你的翻译文件之名称,被显式地开启。特别的,如果你希望这个翻译文件通过这个全新格式化工具来执行,可添加 +intl-icu 后缀。例如,messages.en.xlf 使用的是老式格式化工具,而 messages+intl-icu.en.xlf 使用的是新格式化器。

最后,新的格式化器不建议使用 transChoice() 方法,将被 trans() 方法连同一个被称作 %count% 的参数所取代。