Интернационализация (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 г.
?>