Intl组件

3.4 版本
维护中的版本

本组件是PHP的C intl extension 的一个替代品(replacement layer),它也可以提供对 ICU library 的区域相关数据(localization data)进行访问。

这个替代层,被局限于 “en” locale。如果你需要使用其他locales,你应当 安装intl扩展

安装 

你可以通过下述两种方式安装:

如果你通过Composer安装,当intl extension无法加载时,下列intl扩展的类和方法将被自动提供:

当intl扩展不可用时,以下的类会用于替代intl类:

Composer自动把这些类暴露(exposes)在全局命名空间。

如果你不使用Composer而是用 Symfony ClassLoader组件,在暴露它们时,你需要把以下几行手动添加到autoload代码中:

1
2
3
4
5
if (!function_exists('intl_is_failure')) {
    require '/path/to/Icu/Resources/stubs/functions.php';
 
    $loader->registerPrefixFallback('/path/to/Icu/Resources/stubs');
}

写入和读取资源Bundles 

ResourceBundle 目前不被本组件支持。因此,组件包括了一组readers和writers,以便读取/写入数组(或类数组对象,array-like objects),从/到那些resource bundle文件中。以下的类受到支持:

如果你对如何使用这些类感兴趣,请继续阅读。否则可以跳出本节直接进到 访问ICU数据

TextBundleWriter 

TextBundleWriter 向一个文本型resource bundle写入一个数组或类数组对象。这可以令 .txt 文件通过 BundleCompiler 类,被转换成一个二进制的 .res 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\Intl\ResourceBundle\Writer\TextBundleWriter;
use Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompiler;
 
$writer = new TextBundleWriter();
$writer->write('/path/to/bundle', 'en', array(
    'Data' => array(
        'entry1',
        'entry2',
        // ...
    ),
));
 
$compiler = new BundleCompiler();
$compiler->compile('/path/to/bundle', '/path/to/binary/bundle');

"genrb" 命令必须能用于 BundleCompiler 才可以工作。如果这个命令存在于一个非标准位置,你可以向 BundleCompiler 的构造器传入其路径。

PhpBundleWriter 

PhpBundleWriter 向一个 .php resource bundle 写入一个数组或类数组对象:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Intl\ResourceBundle\Writer\PhpBundleWriter;
 
$writer = new PhpBundleWriter();
$writer->write('/path/to/bundle', 'en', array(
    'Data' => array(
        'entry1',
        'entry2',
        // ...
    ),
));

BinaryBundleReader 

BinaryBundleReader 从一个数组或类数组对象中读取 resource bundle 文件。这个类目前只能在 intl extension 安装的情况下运行::

1
2
3
4
5
6
use Symfony\Component\Intl\ResourceBundle\Reader\BinaryBundleReader;
 
$reader = new BinaryBundleReader();
$data = $reader->read('/path/to/bundle', 'en');
 
var_dump($data['Data']['entry1']);

PhpBundleReader 

PhpBundleReader 从 .php文件中读取 resource bundle ,并返回一个数组或类数组对象:

1
2
3
4
5
6
use Symfony\Component\Intl\ResourceBundle\Reader\PhpBundleReader;
 
$reader = new PhpBundleReader();
$data = $reader->read('/path/to/bundle', 'en');
 
var_dump($data['Data']['entry1']);

BufferedBundleReader 

BufferedBundleReader 对另一个reader打包,但把最后的N个读取保存在一个buffer中(缓冲),此处的N就是传入构造器的buffer容量(size):

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\Intl\ResourceBundle\Reader\BinaryBundleReader;
use Symfony\Component\Intl\ResourceBundle\Reader\BufferedBundleReader;
 
$reader = new BufferedBundleReader(new BinaryBundleReader(), 10);
 
// actually reads the file / 真正读取文件
$data = $reader->read('/path/to/bundle', 'en');
 
// returns data from the buffer / 从缓存中返回数据
$data = $reader->read('/path/to/bundle', 'en');
 
// actually reads the file / 真正读取文件
$data = $reader->read('/path/to/bundle', 'fr');

StructuredBundleReader 

StructuredBundleReader 对另一个reader打包,并提供一个 readEntry() 方法,来读取一个 resource bundle 入口,而毋须担心数组的键是否被设置。如果一个路径不能被解析,会返回 null:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\Intl\ResourceBundle\Reader\BinaryBundleReader;
use Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReader;
 
$reader = new StructuredBundleReader(new BinaryBundleReader());
 
$data = $reader->read('/path/to/bundle', 'en');
 
// Produces an error if the key "Data" does not exist
// 如果"Data"键不存在则产生一个错误
var_dump($data['Data']['entry1']);
 
// Returns null if the key "Data" does not exist
// 如果"Data"键不存在则返回null
var_dump($reader->readEntry('/path/to/bundle', 'en', array('Data', 'entry1')));

此外,readEntry() 方法可以解析fallback locales(地域信息的回滚)。例如,"en_GB" 的fallback locale 是 "en"。对于 single-valued entries (字符串,数字等)来说,如果它不能在更多的特定locale中被找到,这个entry将从回滚的locale中来读取。对于multi-values(数组)来说,更多的特定值和这个回滚的locale将合并。为了抑制这种行为,可把最后一个 $fallback 参数设成 false:

1
2
3
4
5
6
var_dump($reader->readEntry(
    '/path/to/bundle',
    'en',
    array('Data', 'entry1'),
    false
));

访问ICU数据 

ICU data位于几个 "resource bundles" 中。通过静态的 Intl 类,你可以访问这些bunldes的一个PHP wrapper。目前,以下数据受到支持:

语言文字名称 

语言文字的翻译,可以在language bundle中找到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Symfony\Component\Intl\Intl;
 
\Locale::setDefault('en');
 
$languages = Intl::getLanguageBundle()->getLanguageNames();
// => array('ab' => 'Abkhazian', ...)
 
$language = Intl::getLanguageBundle()->getLanguageName('de');
// => 'German'
 
$language = Intl::getLanguageBundle()->getLanguageName('de', 'AT');
// => 'Austrian German'
 
$scripts = Intl::getLanguageBundle()->getScriptNames();
// => array('Arab' => 'Arabic', ...)
 
$script = Intl::getLanguageBundle()->getScriptName('Hans');
// => 'Simplified'

所有的方法,接受locale作为最后一个可选参数,默认值是当前的默认locale:

1
2
$languages = Intl::getLanguageBundle()->getLanguageNames('de');
// => array('ab' => 'Abchasisch', ...)

国名 

国名的翻译,可以在region bundle中找到:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Intl\Intl;
 
\Locale::setDefault('en');
 
$countries = Intl::getRegionBundle()->getCountryNames();
// => array('AF' => 'Afghanistan', ...)
 
$country = Intl::getRegionBundle()->getCountryName('GB');
// => 'United Kingdom'

所有的方法,接受locale作为最后一个可选参数,默认值是当前的默认locale:

1
2
$countries = Intl::getRegionBundle()->getCountryNames('de');
// => array('AF' => 'Afghanistan', ...)

地域(Locales) 

locale名称的翻译,可以在locale bundle中找到:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Intl\Intl;
 
\Locale::setDefault('en');
 
$locales = Intl::getLocaleBundle()->getLocaleNames();
// => array('af' => 'Afrikaans', ...)
 
$locale = Intl::getLocaleBundle()->getLocaleName('zh_Hans_MO');
// => 'Chinese (Simplified, Macau SAR China)'

所有的方法,接受locale作为最后一个可选参数,默认值是当前的默认locale:

1
2
$locales = Intl::getLocaleBundle()->getLocaleNames('de');
// => array('af' => 'Afrikaans', ...)

货币 

货币名称以及货币相关信息的翻译,可以在currency bundle中找到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Symfony\Component\Intl\Intl;
 
\Locale::setDefault('en');
 
$currencies = Intl::getCurrencyBundle()->getCurrencyNames();
// => array('AFN' => 'Afghan Afghani', ...)
 
$currency = Intl::getCurrencyBundle()->getCurrencyName('INR');
// => 'Indian Rupee'
 
$symbol = Intl::getCurrencyBundle()->getCurrencySymbol('INR');
// => '₹'
 
$fractionDigits = Intl::getCurrencyBundle()->getFractionDigits('INR');
// => 2
 
$roundingIncrement = Intl::getCurrencyBundle()->getRoundingIncrement('INR');
// => 0

所有的方法 (除了 getFractionDigits()getRoundingIncrement()) ,接受locale作为最后一个可选参数,默认值是当前的默认locale:

1
2
$currencies = Intl::getCurrencyBundle()->getCurrencyNames('de');
// => array('AFN' => 'Afghanische Afghani', ...)

这就是当前你需要掌握的所有知识!Have fun coding!

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)