Интернационализация (i18n) в PHP: Полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Интернационализация (i18n) в PHP: как сделать сайт многоязычным

Интернационализация (i18n) — это процесс проектирования программного обеспечения таким образом, чтобы его можно было легко адаптировать для различных языков и регионов без внесения изменений в код. В PHP для этого существует несколько мощных инструментов, которые позволяют разделить код и текст, а затем динамически подгружать нужный язык.

В этой статье мы рассмотрим основные подходы и библиотеки для реализации i18n в PHP, включая встроенные функции gettext, расширение intl и популярные библиотеки, такие как Symfony Translation.

1. Основные концепции i18n

Прежде чем перейти к инструментам, важно понять ключевые термины:

  • Локаль (locale) — комбинация языка и региона (например, ru_RU, en_US, de_DE).
  • Перевод — замена исходной строки на её эквивалент на другом языке.
  • Плюрализация — правильное склонение слов в зависимости от числа (например, "1 файл", "2 файла", "10 файлов").
  • Форматирование — адаптация дат, чисел, валют под локаль.

2. Встроенная библиотека gettext

gettext — это классический инструмент для i18n, встроенный в PHP. Он использует файлы .po (Portable Object) и .mo (Machine Object) для хранения переводов.

Установка и настройка

Убедитесь, что расширение gettext включено в php.ini:

extension=gettext

Пример базовой настройки:

<?php
// Устанавливаем локаль
setlocale(LC_ALL, 'ru_RU.UTF-8');
// Указываем домен (имя файла .mo)
bindtextdomain('messages', './locale');
// Кодировка
bind_textdomain_codeset('messages', 'UTF-8');
// Выбираем домен
textdomain('messages');

// Используем перевод
echo gettext("Hello, World!"); // выведет "Здравствуй, Мир!"
// или сокращённо
echo _("Hello, World!");
?>

Структура файлов

Ваши файлы переводов должны лежать в папке locale:

locale/
├── ru_RU/
│   └── LC_MESSAGES/
│       └── messages.po
│       └── messages.mo
└── en_US/
    └── LC_MESSAGES/
        └── messages.po
        └── messages.mo

Пример файла messages.po:

msgid "Hello, World!"
msgstr "Здравствуй, Мир!"

msgid "Files: %d"
msgstr "Файлы: %d"

Для компиляции .po в .mo используйте утилиту msgfmt:

msgfmt messages.po -o messages.mo

3. Расширение intl (Internationalization Functions)

Расширение intl предоставляет более современные возможности для работы с локалями, включая форматирование чисел, дат и сообщений.

Установка

sudo apt-get install php-intl  # для Ubuntu/Debian

Форматирование сообщений с MessageFormatter

<?php
$locale = 'ru_RU';
$message = '{0} приветствует {1}!';
$fmt = new MessageFormatter($locale, $message);
echo $fmt->format(['PHP', 'Мир']);
// Выведет: PHP приветствует Мир!
?>

Плюрализация

<?php
$locale = 'ru_RU';
$pattern = '{0, plural, one {# файл} few {# файла} other {# файлов}}';
$fmt = new MessageFormatter($locale, $pattern);
echo $fmt->format([1]); // 1 файл
echo $fmt->format([2]); // 2 файла
echo $fmt->format([10]); // 10 файлов
?>

Форматирование дат и чисел

<?php
$locale = 'ru_RU';
$fmt = new NumberFormatter($locale, NumberFormatter::DECIMAL);
echo $fmt->format(1234567.89); // 1 234 567,89

$dateFmt = new IntlDateFormatter($locale, IntlDateFormatter::LONG, IntlDateFormatter::NONE);
echo $dateFmt->format(new DateTime()); // 15 марта 2025 г.
?>

4. Библиотека Symfony Translation

Рекомендаций