Реализация локализации на PHP с поддержкой языка en

Раздел: Веб-разработка -> Интернационализация

Основные методы локализации на PHP для языка en

Наиболее эффективное решение - использование расширения gettext с файлами .po/.mo. Оно обеспечивает стандартизированный подход, поддержку плюральных форм, контекста и кеширование переводов. Для английского языка (en) достаточно создать один файл перевода и подключить его через функцию bindtextdomain().

// index.php
putenv('LC_ALL=en_US.UTF-8');
setlocale(LC_ALL, 'en_US.UTF-8');
bindtextdomain('messages', './locale');
textdomain('messages');
echo _('Hello, world!');

Php loc index php (локализация в php)

Пояснение: сначала устанавливается локаль en_US.UTF-8, затем указывается домен (messages) и путь к каталогу с файлами .mo. Функция _() (или gettext()) автоматически извлекает перевод.

Типичные ошибки:

  • Отсутствие установленной локали в системе (проверка командой locale -a).
  • Неправильная структура каталогов: locale/en_US/LC_MESSAGES/messages.mo.
  • Не сброшен кеш opcache после обновления .mo файла.

Как организовать переводы через простые массивы без внешних инструментов?

Для небольших проектов подходит хранение переводов в PHP-массиве. Файл lang/en.php возвращает ассоциативный массив со строками.

// lang/en.php
return [
    'greeting' => 'Hello',
    'farewell' => 'Goodbye'
];

// index.php
$lang = $_GET['lang'] ?? 'en';
$translations = include __DIR__ . "/lang/{$lang}.php";
echo $translations['greeting'] ?? $translations['fallback'];

Index php en (локализация (язык en))

Цель: быстрый старт без дополнительных расширений. Используется для статических сайтов или прототипов.

Проблемы: отсутствие плюральных форм, сложность поддержки большого количества языков, ручное управление ключами.

Как использовать JSON файлы для хранения переводов?

JSON - удобный формат для обмена данными. Файл en.json содержит переводы в виде объекта.

// en.json
{"greeting": "Hello", "farewell": "Goodbye"}

// index.php
$lang = $_GET['lang'] ?? 'en';
$json = file_get_contents(__DIR__ . "/{$lang}.json");
$translations = json_decode($json, true);
echo $translations['greeting'];

Action php lang (язык в php (локализация))

Цель: простота редактирования, возможность использовать готовые инструменты для перевода (например, Crowdin). Подходит для одностраничных приложений.

Типичные ошибки: неправильная кодировка (BOM), отсутствие проверки существования файла, некорректный JSON (лишние запятые).

Как реализовать переводы через базу данных для динамического управления?

Если переводы нужно часто менять без редактирования кода, используют БД (например, MySQL). Таблица translations содержит ключ, язык и значение.

// index.php
$lang = $_GET['lang'] ?? 'en';
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('SELECT value FROM translations WHERE `key` = :key AND lang = :lang');
$stmt->execute([':key' => 'greeting', ':lang' => $lang]);
$row = $stmt->fetch();
echo $row['value'];

Цель: централизованное управление переводами через админ-панель. Подходит для CMS и корпоративных порталов.

Проблемы: снижение производительности при каждом запросе (решение - кеширование в memcached или Redis), сложность обработки плюральных форм.

Как использовать библиотеку intl для форматирования с учетом локали?

Расширение intl предоставляет класс MessageFormatter для перевода с подстановкой переменных и плюральными формами.

// index.php
$fmt = new MessageFormatter('en_US', '{0} {1} have {2, plural, one {# apple} other {# apples}}.');
echo $fmt->format(['Today', 'you', 5]);
// Output: Today you have 5 apples.

Цель: локализация чисел, дат, валют и плюральных форм без отдельных файлов перевода. Требует установки расширения intl.

Ошибки: неправильный синтаксис шаблона, отсутствие локали en_US в системе.

Расширенные примеры кода и результатов

Полная настройка gettext с плюральными формами

Создание .po файла с плюральными формами для английского языка:

Пример
# locale/en_US/LC_MESSAGES/messages.po
msgid "%d apple"
msgid_plural "%d apples"
msgstr[0] "%d apple"
msgstr[1] "%d apples"

Компиляция в .mo:

Пример
msgfmt messages.po -o messages.mo

PHP-код с выбором формы:

Пример
// index.php
putenv('LC_ALL=en_US.UTF-8');
setlocale(LC_ALL, 'en_US.UTF-8');
bindtextdomain('messages', './locale');
textdomain('messages');

$count = 3;
echo sprintf(ngettext('%d apple', '%d apples', $count), $count);
// Output: 3 apples

Результат:

3 apples

Массив переводов с вложенными категориями и fallback

Пример
// lang/en.php
return [
    'nav' => [
        'home' => 'Home',
        'about' => 'About Us'
    ],
    'errors' => [
        '404' => 'Page not found'
    ]
];

// index.php
$lang = $_GET['lang'] ?? 'en';
$translations = include __DIR__ . "/lang/{$lang}.php";

function t($key, $fallback = '') {
    global $translations;
    $keys = explode('.', $key);
    $value = $translations;
    foreach ($keys as $k) {
        if (!isset($value[$k])) return $fallback;
        $value = $value[$k];
    }
    return $value;
}

echo t('nav.home'); // Home
echo t('nav.contact', 'Contact'); // Contact (fallback)

Результат:

HomeContact

JSON переводы с интерполяцией переменных

Пример
// en.json
[
  {
    "key": "welcome",
    "value": "Welcome, {name}!"
  }
]

// index.php
$lang = 'en';
$json = file_get_contents("{$lang}.json");
$translations = json_decode($json, true);
$map = [];
foreach ($translations as $item) {
    $map[$item['key']] = $item['value'];
}

$name = 'John';
$message = str_replace('{name}', $name, $map['welcome']);
echo $message;

Результат:

Welcome, John!

Переводы через базу данных с кешированием в файле

Пример
// index.php
$lang = 'en';
$cacheFile = __DIR__ . "/cache/{$lang}.php";
if (file_exists($cacheFile)) {
    $translations = include $cacheFile;
} else {
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    $stmt = $pdo->query("SELECT `key`, value FROM translations WHERE lang = '$lang'");
    $translations = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $translations[$row['key']] = $row['value'];
    }
    file_put_contents($cacheFile, '<? return ' . var_export($translations, true) . ';');
}
echo $translations['greeting'];

Результат:

Hello

intl MessageFormatter с валютой и датой

Пример
// index.php
$fmt = new MessageFormatter('en_US', 'At {0, time} on {0, date}, you paid {1, number, currency}.');
echo $fmt->format([new DateTime(), 1234.56]);

Результат:

At 10:30:00 AM on Jan 1, 2025, you paid $1,234.56.

Локализация (язык en) - comments

En
Index php en (php)