Если ваш сайт выходит за пределы одной страны, рано или поздно встанет вопрос: как сделать его удобным для пользователей, говорящих на разных языках? Мультиязычность — это не просто перевод текста, а целая система, которая включает маршрутизацию, хранение переводов, работу с URL и многое другое. В этой статье мы разберем, как реализовать мультиязычность в Yii2 — одном из самых популярных PHP-фреймворков. Я покажу, как настроить все с нуля, дам примеры кода и поделюсь лайфхаками, которые сэкономят вам часы работы.
С чего начать: базовые понятия
Прежде чем погружаться в код, давайте разберемся, что такое мультиязычность в контексте Yii2. Фреймворк предоставляет встроенные инструменты для интернационализации (i18n) — это набор функций, которые позволяют переводить сообщения, форматировать даты и числа в зависимости от локали. Локаль — это комбинация языка и региона, например, en-US или ru-RU.
Основная идея такова: вы пишете код с использованием специальных меток, а Yii2 подставляет нужный перевод в зависимости от выбранной локали. Это похоже на шаблон, куда подставляются значения. Но чтобы все заработало, нужно правильно настроить приложение.
В Yii2 есть два подхода к хранению переводов: файловый (например, PHP-массивы или JSON) и базовый (хранение в базе данных). Файловый подход проще для небольших проектов, базовый — для больших, где переводы обновляются динамически. Мы рассмотрим оба варианта, но начнем с файлового.
Настройка приложения для работы с языками
Первый шаг — настроить компонент i18n в конфигурационном файле приложения (обычно это config/web.php). Здесь мы указываем, где хранятся переводы и какие языки поддерживаются. Вот базовый пример:
'components' => [
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@app/messages',
'sourceLanguage' => 'ru-RU',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',
],
],
],
],
],
Здесь basePath указывает на папку, где лежат файлы переводов, а sourceLanguage — язык, на котором написан исходный код (обычно это язык разработчика). Обратите внимание на паттерн app* — он говорит, что все категории, начинающиеся с 'app', будут использовать этот источник.
Теперь создадим файлы переводов. Для каждого языка создается папка с локалью, например, messages/en-US/app.php. Внутри — массив, где ключи — это исходные строки, а значения — переводы:
// messages/en-US/app.php
return [
'Привет, мир!' => 'Hello, world!',
'Добро пожаловать' => 'Welcome',
];
Чтобы использовать переводы в коде, достаточно вызвать метод Yii::t():
// В контроллере или представлении
echo Yii::t('app', 'Привет, мир!');
Если перевода нет, Yii2 просто выведет исходную строку — это удобно для отладки.
Маршрутизация с учетом языка
Теперь самое интересное — как сделать так, чтобы пользователь мог переключать язык, и чтобы URL отражал выбранную локаль. Есть несколько стратегий:
- Использовать поддомены (en.site.com, ru.site.com).
- Использовать префикс в URL (site.com/en, site.com/ru).
- Использовать параметр запроса (site.com?lang=en).
Я рекомендую второй вариант — префикс в URL. Он прост в реализации и понятен пользователям. Для этого нужно настроить URL-правила в компоненте urlManager. Вот как это сделать:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<lang:(en|ru)>/<controller>/<action>' => '<controller>/<action>',
],
],
Теперь нам нужно определить текущий язык в приложении. Это можно сделать в компоненте beforeAction события приложения или в базовом контроллере. Например, создадим компонент LanguageSelector:
class LanguageSelector extends Component
{
public function init()
{
parent::init();
// Определяем язык из URL
$lang = Yii::$app->request->get('lang');
if ($lang && in_array($lang, ['en', 'ru'])) {
Yii::$app->language = $lang === 'en' ? 'en-US' : 'ru-RU';
} else {
// Если язык не указан, используем язык браузера или по умолчанию
Yii::$app->language = 'ru-RU';
}
}
}
Подключаем этот компонент в конфигурации:
'components' => [
'languageSelector' => [
'class' => 'app\components\LanguageSelector',
],
],
Теперь при обращении к site.com/en/contact язык будет английский, а при site.com/ru/contact — русский. Осталось только добавить переключатель языка на сайте — это может быть ссылка или выпадающий список.
Перевод динамического контента из базы данных
Статические строки мы перевели, но что делать с контентом, который хранится в базе данных? Например, у нас есть таблица posts, и мы хотим, чтобы заголовок и текст были на разных языках. Самый простой способ — создать дополнительные поля для каждого языка, например, title_ru, title_en. Но это не очень гибко.
Лучше использовать отдельные таблицы для переводов. Например, у нас есть таблица post с полями id, created_at, и таблица post_lang с полями post_id, lang, title, content. Тогда мы можем легко получать нужный перевод в зависимости от текущего языка.
В модели Post можно определить связь с переводами:
class Post extends \yii\db\ActiveRecord
{
public function getTranslations()
{
return $this->hasMany(PostLang::className(), ['post_id' => 'id']);
}
public function getTranslation($lang = null)
{
$lang = $lang ?: Yii::$app->language;
return $this->getTranslations()->where(['lang' => $lang])->one();
}
}
В представлении мы можем получить перевод так:
$translation = $post->getTranslation();
echo $translation->title;
Этот подход легко масштабируется: если добавится новый язык, просто добавим записи в таблицу переводов, не меняя структуру основной таблицы.
Практические советы и лайфхаки
Вот несколько советов, которые помогут вам избежать типичных ошибок и упростить жизнь:
- Всегда указывайте
sourceLanguageв конфигурации i18n — это поможет избежать путаницы. - Используйте категории для переводов: например,
app,app/error,app/form. Это упростит поиск нужных строк. - Для дат и чисел используйте встроенные форматтеры Yii2 — они автоматически адаптируются под локаль.
- Не забывайте про кэширование переводов: в production-режиме включите кэш, чтобы не читать файлы каждый раз.
Также рекомендую хранить все переводы в одном месте, например, в папке messages, и использовать единый стиль именования ключей. Это облегчит работу с ними и уменьшит количество ошибок.
Сравнение подходов к хранению переводов
| Подход | Плюсы | Минусы |
|---|---|---|
| Файловые переводы | Простота, быстрота, удобно для статики | Не подходит для динамического контента |
| Переводы в БД | Гибкость, возможность редактирования через админку | Требует дополнительных запросов, сложнее в настройке |
Выбор подхода зависит от вашего проекта. Если сайт простой — хватит файлов. Если контент постоянно обновляется — лучше использовать БД.
Итог: что мы получили
Мы рассмотрели основные шаги для реализации мультиязычности в Yii2: настройку компонента i18n, маршрутизацию с префиксом языка, перевод статических строк и динамического контента. Теперь вы можете сделать свой сайт доступным для пользователей из разных стран.
Помните, что мультиязычность — это не только перевод текста, но и адаптация форматов дат, чисел, валют. Yii2 предоставляет все необходимые инструменты, так что не бойтесь экспериментировать.
Если у вас остались вопросы — загляните в официальную документацию Yii2 или обратитесь к сообществу. Удачи в разработке!



