Компонент Intl

Заменяющий PHP слой для C расширения intl, который также предоставляет доступ к локализации данных библиотеки ICU.

Caution

Заменяющий слой ограничен локалью "en". Если вы хотите использовать другие локали, вам стоит установить расширение intl.

Эта статья объясняет как использовать функции Intl как независимого компонента в любом приложении PHP. Прочитайте статью Translations для понимания как делать интернационализацию и управлять пользовательскими локалями в приложениях Symfony.

Установка

1
$ composer require symfony/intl

Также вы можете клонировать репозиторий https://github.com/symfony/intl.

Note

If you install this component outside of a Symfony application, you must require the vendor/autoload.php file in your code to enable the class autoloading mechanism provided by Composer. Read this article for more details.

Если вы установите компонент через Composer, то следующие классы и функции рашсирения intl будут предоставлены автоматически, если расширение intl не загружено:

Когда расширение intl недоступно, для замены intl классов используются следующие классы:

Composer автоматически демонстрирует эти классы в глобальном пространстве имён.

Написание и чтение пакетов источников

Класс ResourceBundle на данный момент не поддерживается этим компонентом. Вместо этого, он включает в себя набор читателей и писателей для чтения и написания массивов (или массивоподобных объектов) из / в файлы пакета источников. Поддерживаются следующие классы:

Продолжайте читать, если вам интересно, как использовать эти классы. В противном случае - пропустите этот раздел и перейдите к Доступ к данным ICU.

TextBundleWriter

TextBundleWriter пишет массив или массивоподобный объект в простой текстовый пакет источников. Итоговый .txt файл может быть преобразован в бинарный .res файл с помощью класса BundleCompiler:

 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:

 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 читает бинарные файлы пакета источников и возвращает массив или массивоподобный объект. Этот класс на данный момент работает только с установленным расширением intl:

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 и возвращает массив или массивоподобный объект:

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 выступает оболочкой другого читателя, но держит последние N прочтений в буфере, где N - размер буфера, переданный конструктору:

 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);

// на самом деле читает файл
$data = $reader->read('/path/to/bundle', 'en');

// возвращает данные из буфера
$data = $reader->read('/path/to/bundle', 'en');

// на самом деле читает файл
$data = $reader->read('/path/to/bundle', 'fr');

StructuredBundleReader

StructuredBundleReader выступает оболочкой другого читателя и предлагает метод readEntry() для чтения записи пакета источников, без опасений о том, установлены ли ключи массива. Если путь не может быть разрешён, возвращается null:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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');

// производит ошибку, если ключ "Data" не существует
var_dump($data['Data']['entry1']);

// возвращает "null", если ключ "Data" не существует
var_dump($reader->readEntry('/path/to/bundle', 'en', array('Data', 'entry1')));

Кроме того, метод readEntry() разрещает резервные локали. Например, резервная локаль "en_GB" - "en". Для однозначных записей (строк, чисел и др.), запись будет считана из резервной локали, если она не можетбыть найдена в более конкретной локали. Для многозначных записей (массивов), значения более конкретной и резервной локали будут объединены. Для того, чтобы подавить это поведение, последний параметр $fallback может быть установлен, как false:

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

Доступ к данным ICU

Данные ICU расположены в нескольких "пакетах источников". Вы можете получить доступ к PHP-обёртке этих пакетов через статичный класс Intl. На данный момент поддерживаются следующие данные:

Язык и названия скриптов

Переводы языков и названий скриптов можно найти в пакете языков:

 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' => 'Абхазский', ...)

$language = Intl::getLanguageBundle()->getLanguageName('de');
// => 'Немецкий'

$language = Intl::getLanguageBundle()->getLanguageName('de', 'AT');
// => 'Австрийский немецкий'

$scripts = Intl::getLanguageBundle()->getScriptNames();
// => array('Араб' => 'Арабский', ...)

$script = Intl::getLanguageBundle()->getScriptName('Hans');
// => 'Упрощённый'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение текущей локали:

1
2
$languages = Intl::getLanguageBundle()->getLanguageNames('de');
// => array('ab' => 'Абхахский', ...)

Названия стран

Переводы названий стран можно найти в пакете регионов:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Intl\Intl;

\Locale::setDefault('en');

$countries = Intl::getRegionBundle()->getCountryNames();
// => array('AF' => 'Афганистан', ...)

$country = Intl::getRegionBundle()->getCountryName('GB');
// => 'Великобритания'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение текущей локали:

1
2
$countries = Intl::getRegionBundle()->getCountryNames('de');
// => array('AF' => 'Афганистан', ...)

Локали

Переводы названий локалей можно найти в пакете локалей:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Intl\Intl;

\Locale::setDefault('en');

$locales = Intl::getLocaleBundle()->getLocaleNames();
// => array('af' => 'Африкаанс', ...)

$locale = Intl::getLocaleBundle()->getLocaleName('zh_Hans_MO');
// => 'Китайский (Упрощённый, Макау Китай)'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение текущей локали:

1
2
$locales = Intl::getLocaleBundle()->getLocaleNames('de');
// => array('af' => 'Африкаанс', ...)

Валюты

Переводы названий валют и другой информации, связанной с валютами, можно найти в пакете валют:

 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' => 'Афганские афгани', ...)

$currency = Intl::getCurrencyBundle()->getCurrencyName('INR');
// => 'Индийские рупии'

$symbol = Intl::getCurrencyBundle()->getCurrencySymbol('INR');
// => '₹'

$fractionDigits = Intl::getCurrencyBundle()->getFractionDigits('INR');
// => 2

$roundingIncrement = Intl::getCurrencyBundle()->getRoundingIncrement('INR');
// => 0

Все методы (кроме getFractionDigits() и getRoundingIncrement()) принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение текущей локали:

1
2
$currencies = Intl::getCurrencyBundle()->getCurrencyNames('de');
// => array('AFN' => 'Афганские афгани', ...)

Это всё, что вам нужно знать на сейчас. Приятного написания кода!

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.