Многоязычность
Многоязычность использует symfony/translation компонент.
Установка
composer require symfony/translation
Создание языкового пакета
По умолчанию вебмен размещает языковой пакет в папке resource/translations
(если папка отсутствует, создайте её самостоятельно). Чтобы изменить директорию, настройте это в файле config/translation.php
. Каждому языку соответствует одна из поддиректорий, определение языка по умолчанию хранится в файле messages.php
. Пример:
resource/
└── translations
├── en
│ └── messages.php
└── zh_CN
└── messages.php
Все языковые файлы возвращают массив, например:
// resource/translations/en/messages.php
return [
'hello' => 'Hello webman',
];
Настройка
config/translation.php
return [
// Язык по умолчанию
'locale' => 'zh_CN',
// Язык для возврата. Если перевод не найден в текущем языке, пробуем использовать перевод из языка для возврата
'fallback_locale' => ['zh_CN', 'en'],
// Папка для хранения языковых файлов
'path' => base_path() . '/resource/translations',
];
Перевод
Перевод осуществляется с помощью метода trans()
.
Создайте языковой файл resource/translations/zh_CN/messages.php
следующим образом:
return [
'hello' => '你好 世界!',
];
Создайте файл app/controller/UserController.php
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request)
{
$hello = trans('hello'); // 你好 世界!
return response($hello);
}
}
Обратившись по адресу http://127.0.0.1:8787/user/get
, вы получите "你好 世界!"
Изменение языка по умолчанию
Для смены языка используется метод locale()
.
Добавьте языковой файл resource/translations/en/messages.php
следующим образом:
return [
'hello' => 'hello world!',
];
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request)
{
// Смена языка
locale('en');
$hello = trans('hello'); // hello world!
return response($hello);
}
}
Обратившись по адресу http://127.0.0.1:8787/user/get
, вы получите "hello world!"
Вы также можете использовать 4-й параметр функции trans()
для временной смены языка, например, данный пример эквивалентен предыдущему:
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request)
{
// 4-й параметр смена языка
$hello = trans('hello', [], null, 'en'); // hello world!
return response($hello);
}
}
Явная установка языка для каждого запроса
Перевод является одиночным экземпляром, это означает, что все запросы используют этот экземпляр. Если какой-либо запрос использует locale()
для установки языка по умолчанию, это повлияет на все последующие запросы в этом процессе. Поэтому мы должны явным образом устанавливать язык для каждого запроса. Например, используйте следующий миддлвар
Создайте файл app/middleware/Lang.php
(если директория не существует, создайте её самостоятельно) следующим образом:
<?php
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class Lang implements MiddlewareInterface
{
public function process(Request $request, callable $handler) : Response
{
locale(session('lang', 'zh_CN'));
return $handler($request);
}
}
В файле config/middleware.php
добавьте глобальный миддлвар следующим образом:
return [
// Глобальные миддлвары
'' => [
// ... здесь опущены другие миддлвары
app\middleware\Lang::class,
]
];
Использование плейсхолдеров
Иногда сообщение содержит переменные, которые необходимо перевести, например:
trans('hello ' . $name);
При возникновении такой ситуации мы используем плейсхолдеры для обработки.
Измените resource/translations/zh_CN/messages.php
следующим образом:
return [
'hello' => '你好 %name%!',
];
При переводе передавайте данные через второй параметр, чтобы сопоставить значение плейсхолдера.
trans('hello', ['%name%' => 'webman']); // 你好 webman!
Обработка множественного числа
Некоторые языки используют разные формы в зависимости от количества предметов, например There is %count% apple
, когда %count%
равно 1, фраза корректна, когда больше 1 — неверна.
В таких случаях мы используем трубку (|
), чтобы перечислить формы множественного числа.
В языковом файле resource/translations/en/messages.php
добавьте apple_count
следующим образом:
return [
// ...
'apple_count' => 'There is one apple|There are %count% apples',
];
trans('apple_count', ['%count%' => 10]); // There are 10 apples
Мы даже можем задать диапазон чисел и создать более сложные правила множественного числа:
return [
// ...
'apple_count' => '{0} There are no apples|{1} There is one apple|]1,19] There are %count% apples|[20,Inf[ There are many apples'
];
trans('apple_count', ['%count%' => 20]); // There are many apples
Указание языкового файла
По умолчанию имя языкового файла равно messages.php
, однако вы можете создать языковые файлы с другими именами.
Создайте языковой файл resource/translations/zh_CN/admin.php
следующим образом:
return [
'hello_admin' => '你好 管理员!',
];
Чрезвычайно важно установить языковой файл через третий параметр trans()
(опуская .php
суффикс).
trans('hello', [], 'admin', 'zh_CN'); // 你好 管理员!