Home > Article > Backend Development > [PHP](译)Localization Demystified: Php-Intl for Everyone
原文地址: https://www.sitepoint.com/localization-demystified-understanding-php-intl/
大多数应用程序执行场可以识别类似处理文本,日期,时区等的操作。而 PHP Intl 的扩展功能可提供一个良好的 API ,用以连接广为人知的 ICU 库的功能。
此扩展功能默认安装在 PHP 5.3 及以上的版本,你可以通过以下命令进行查找:
php -m | grep 'intl'
如果此扩展功能不存在,你可以按照 安装指南 手动进行安装。如果你使用 Ubuntu,你可以直接使用以下命令安装:
sudoapt-getupdatesudoapt-getinstallphp5-intl
如果你使用的是 PHP 7,你需要添加 PPA ( ppa:ondrej/php ),升级你的系统并且安装扩展功能 Intl。
# 添加 PPAsudoadd-apt-repositoryppa:ondrej/php-7.0# 升级索引库sudoapt-getupdate# 安装扩展功能sudoapt-getinstallphp7.0-intl
大多数现代化应用在搭建的时候非常注意本地。有时候,这些消息是一个简单的拥有变量占位符的字符串,有时却是一个复杂的多元化的字符串。
我们会从一个包含占位符的简单信息开始。占位符是被封闭在花括号中的字符。这里有一个示例:
var_dump( MessageFormatter::formatMessage( "en_US", "I have {0, number, integer} apples.", [ 3 ] )); // output string(16) "I have 3 apples."
传递提要给 MessageFormatter::formatMessage 的类函数如下:
占位符 {0, number, integer} 会键入一个数——整数作为该数据库阵列的第一个项目(看看下面列出选项的表格)我们还可以在占位符中使用命名参数。下面的示例会输出同样的结果。
var_dump( MessageFormatter::formatMessage( "en_US", "I have {number_apples, number, integer} apples.", [ 'number_apples' => 3 ] ));
不同的语言有不同的数字写法,比如阿拉伯语、印度语等等。
先前的示例指向 en_US 环境,让我们换成 ar 环境并看看有什么不同。
var_dump( MessageFormatter::formatMessage( "ar", "I have {number_apples, number, integer} apples.", [ 'number_apples' => 3 ] )); string(17) "I have ٣ apples."
让我们再换成孟加拉语情景( bn ).
var_dump( MessageFormatter::formatMessage( "bn", "I have {number_apples, number, integer} apples.", [ 'number_apples' => 3 ] )); string(18) "I have ৩ apples."
到目前为止,我们只说明了数字。现在让我们看看其他可以使用的类型。
$time = time();var_dump( MessageFormatter::formatMessage( "en_US", "Today is {0, date, full} - {0, time}", array( $time )) ); string(47) "Today is Wednesday, April 6, 2016 - 11:21:47 PM"
var_dump( MessageFormatter::formatMessage( "en_US", "duration: {0, duration}", array( $time )) ); string(23) "duration: 405,551:27:58"
我们也可以表示分数。
var_dump( MessageFormatter::formatMessage( "en_US", "I have {0, spellout} apples", array( 34 )) ); string(25) "I have thirty-four apples"
这对不同的语言环境也适用。
var_dump( MessageFormatter::formatMessage( "ar", "لدي {0, spellout} تفاحة", array( 34 )) ); string(44) "لدي أربعة و ثلاثون تفاحة"
本地化应用程序的一个重要组成部分是管理多元信息使得用户界面尽可能直观。上面苹果的示例就能说明这一点。下面是这个示例中的信息表现:
var_dump( MessageFormatter::formatMessage( "en_US", 'I have {number_apples, plural, =0{no apples} =1{one apple} other{# apples}}', array('number_apples' => 10)) );
// number_apples = 0string(16) "I have no apples" // number_apples = 1string(16) "I have one apple" // number_apples = 10string(16) "I have 10 apples"
这种语法真的很简单直接,并且大多数包都包含这种语法。跟多细节请见 此文件 。
{data, plural, offsetValue =value{message}... other{message}}
有时候,我们需要列出每一个值域的不同信息。比如下面的示例:
var_dump( MessageFormatter::formatMessage( "en_US", 'The value of {0,number} is {0, choice, 0 # between 0 and 19 | 20 # between 20 and 39 | 40 # between 40 and 59 | 60 # between 60 and 79 | 80 # between 80 and 100 | 100 < more than 100 }', array(60)) ); string(38) "The value of 60 is between 60 and 79 "
argType 在这里是为 choice 设定的,语法如下:
{value, choice, choiceStyle}
ICU 文件 的官方定义如下:
choiceStyle = numberseparatormessage ('|' numberseparatormessage)* number = normal_number | ['-'] ∞ (U+221E, infinity)normal_number = double value (unlocalizedASCIIstring) separator = less_than | less_than_or_equalless_than = '<'less_than_or_equal = '#' | ≤ (U+2264)
注意: ICU 开发者不鼓励使用选择类型。
有时我们需要选择选项UI组件。个人资料页使用这种方法根据用户的性别等等更新 UI 信息。这里有一个例子:
var_dump( MessageFormatter::formatMessage( "en_US", "{gender, select, ". "female {She has some apples} ". "male {He has some apples.}". "other {It has some apples.}". "}", array('gender' => 'female')) );string(19) "She has some apples"
模式定义如下:
{value, select, selectStyle} // selectStyleselectValue {message} (selectValue {message})*
message 提要会包括类似选项和复数的其他模式。下一个部分会解释一个被我们结合了多个模式的例子。
到目前为止,我们已经看过例如选择、多元化等等的简单示例。但很多情况会复杂的多。 ICU 文档 有一个很好的例子来说明这一点。为了便于理解,我们一段一段来看。
var_dump( MessageFormatter::formatMessage( "en_US", "{gender_of_host, select, ". "female {She has a party} ". "male {He has some apples.}". "other {He has some apples.}". "}", array('gender_of_host' => 'female', "num_guests" => 5, 'host' => "Hanae", 'guest' => 'Younes' )) );
这是我们之前用的一个相同的例子,不同于之前使用简单信息,我们依赖 num_guests 值定制了下(讨论的是多元化的案例)。
var_dump( MessageFormatter::formatMessage( "en_US", "{gender_of_host, select, ". "female {". "{num_guests, plural, offset:1 ". "=0 {{host} does not have a party.}". "=1 {{host} invites {guest} to her party.}". "=2 {{host} invites {guest} and one other person to her party.}". "other {{host} invites {guest} and # other people to her party.}}}". "male {He has some apples.}". "other {He has some apples.}}", array('gender_of_host' => 'female', "num_guests" => 5, 'host' => "Hanae", 'guest' => 'Younes' )) );
需要注意我们使用了 offset:1 从 num_guests 中移除一个 guest。
string(53) "Hanae invites Younes and 4 other people to her party."
下面是示例的完整段。
var_dump( MessageFormatter::formatMessage( "en_US", "{gender_of_host, select, ". "female {". "{num_guests, plural, offset:1 ". "=0 {{host} does not have a party.}". "=1 {{host} invites {guest} to her party.}". "=2 {{host} invites {guest} and one other person to her party.}". "other {{host} invites {guest} and # other people to her party.}}}". "male {". "{num_guests, plural, offset:1 ". "=0 {{host} does not have a party.}". "=1 {{host} invites {guest} to his party.}". "=2 {{host} invites {guest} and one other person to his party.}". "other {{host} invites {guest} and # other people to his party.}}}". "other {". "{num_guests, plural, offset:1 ". "=0 {{host} does not have a party.}". "=1 {{host} invites {guest} to their party.}". "=2 {{host} invites {guest} and one other person to their party.}". "other {{host} invites {guest} and # other people to their party.}}}}", array('gender_of_host' => 'female', "num_guests" => 5, 'host' => "Hanae", 'guest' => 'Younes' )) );
改变客人的数量来测试所有的信息类型:
// num_guests = 2string(55) "Hanae invites Younes and one other person to her party." // num_guests = 1string(34) "Hanae invites Younes to her party." // num_guests = 0string(28) "Hanae does not have a party."
对于解析信息没有太多可以说;我们使用之前的模式从输出信息中来格式化额外信息。
$messageFormater = new MessageFormatter("en_US", 'I have {0, number}');var_dump( $messageFormater->parse("I have 10 apples") ); array(1) { [0]=> int(10)}
查看 文档 以获取更多关于信息解析的内容。
在这篇介绍性的文章中,我们了解了使用 PHP Intel 的扩展功能来本地化我们的信息。接下来的部分会涉及格式化数字和日期,以及日历的使用。如果你对以上内容有任何疑惑,请给我们留言。