国际化(Internationalization)¶
国际化是指在设计软件时,使它可以无需做大的改变就能够适应不同的语言和地区的需要。对于 Web 应用程序,这有着特别重要的意义,因为潜在的用户可能会在全球范围内。
区域和语言(Locale And Language)¶
Phalcon 通过 Phalcon\Translate\Adapter\NativeArray 和 Phalcon\Translate\Adapter\Gettext 提供了一套轻量级的语言翻译功能。
<?php
$t = new \Phalcon\Translate\Adapter\Gettext(array(
'locale' => 'zh_CN.utf8',
'defaultDOMain' => 'messages',
'directory' => __DIR__ . DIRECTORY_SEPARATOR . 'locale'
));
echo $t->_('Hello');
创建消息列表(Creating Messages)¶
通过以下命令我们可以提取代码中所有类似 _("translate this words")
文本生成 zh_CN.po 文件。
$ xgettext -f *.php -d zh_CN --keyword=_ --from-code=UTF-8
接着,我们可以使用工具(poedit、vim、gedit) 对生成的 po 文件进行翻译,翻译完成后生成 mo 文件:
$ msgfmt -o zh_CN.mo zh_CN.po
最后将 mo 文件拷贝到目录 locale/zh_CN.utf8/LC_MESSAGES。
消息格式化(Message Format)¶
在要翻译的消息里,你可以嵌入一些占位符,并让它们通过动态的参数值来代替。你甚至可以根据目标语言格式的参数值来使用特殊的占位符。 在下面的例子中, 占位符 {username} 在 “Hello, {username}!” 中将分别被 ‘Alexander’和’Qiang’ 所替换。
<?php
$username = 'Phalcon';
// 输出:“Hello, Phalcon”
echo $t->_('Hello, %username%!', [
'username' => $username,
]);
占位符也可以是从零开始的整数序列,比如下面的例子中, %0%、%1% 和 %2% 将分别被 $price、$count 和 $total 所替换。
<?php
$price = 100;
$count = 1;
$total = 200;
echo $t->_('Price: {0}, Count: {1}, Total: {2}', [
$price, $count, $total
]);
追踪消息文件(Trace Message File)¶
如果出现无法翻译指定语言的情况,我们可以通过下面的方式追踪程序读取的语言文件:
$ strace -e trace=open,read php test.php
使用扩展 intl(Use Intl)¶
实现国际化,我们还可以使用 PECL 扩展 intl,想了解更多可以查看 PHP manual,下面简单介绍 intl 在 Phalcon 如何使用。
匹配最佳的区域设置(Find out best available Locale)¶
There are several ways to find out the best available locale using intl. One of them is to check the HTTP “Accept-Language” header:
<?php
$locale = Locale::acceptFromHttp($_SERVER["HTTP_ACCEPT_LANGUAGE"]);
// Locale could be something like "en_GB" or "en"
echo $locale;
Below method returns a locale identified. It is used to get language, culture, or regionally-specific behavior from the Locale API.
Examples of identifiers include:
- en-US (English, United States)
- ru-RU (Russian, Russia)
- zh-HAnt-TW (Chinese, Traditional Script, Taiwan)
- fr-CA, fr-FR (French for Canada and France respectively)
基于区域设置格式化信息(Formatting messages based on Locale)¶
Part of creating a localized application is to produce concatenated, language-neutral messages. The MessageFormatter allows for the production of those messages.
Printing numbers formatted based on some locale:
<?php
// Prints € 4 560
$formatter = new MessageFormatter("fr_FR", "€ {0, number, integer}");
echo $formatter->format(array(4560));
// Prints USD$ 4,560.5
$formatter = new MessageFormatter("en_US", "USD$ {0, number}");
echo $formatter->format(array(4560.50));
// Prints ARS$ 1.250,25
$formatter = new MessageFormatter("es_AR", "ARS$ {0, number}");
echo $formatter->format(array(1250.25));
Message formatting using time and date patterns:
<?php
// Setting parameters
$time = time();
$values = array(7, $time, $time);
// Prints "At 3:50:31 PM on Apr 19, 2015, there was a disturbance on planet 7."
$pattern = "At {1, time} on {1, date}, there was a disturbance on planet {0, number}.";
$formatter = new MessageFormatter("en_US", $pattern);
echo $formatter->format($values);
// Prints "À 15:53:01 le 19 avr. 2015, il y avait une perturbation sur la planète 7."
$pattern = "À {1, time} le {1, date}, il y avait une perturbation sur la planète {0, number}.";
$formatter = new MessageFormatter("fr_FR", $pattern);
echo $formatter->format($values);
特定区域设置的字符串比较(Locale-Sensitive comparison)¶
The Collator class provides string comparison capability with support for appropriate locale-sensitive sort orderings. Check the examples below on the usage of this class:
<?php
// Create a collator using Spanish locale
$collator = new Collator("es");
// Returns that the strings are equal, in spite of the emphasis on the "o"
$collator->setStrength(Collator::PRIMARY);
var_dump($collator->compare("una canción", "una cancion"));
// Returns that the strings are not equal
$collator->setStrength(Collator::DEFAULT_VALUE);
var_dump($collator->compare("una canción", "una cancion"));
音译(Transliteration)¶
Transliterator provides transliteration of strings:
<?php
$id = "Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();";
$transliterator = Transliterator::create($id);
$string = "garçon-étudiant-où-L'école";
echo $transliterator->transliterate($string); // garconetudiantoulecole