есть сайт на php, вход регистрация и тд, собственно хотелось бы сделать его многоязычным, посдкажите как это нормально можно сделать, хочется что то типа такого
К примеру есть папка "lang" в ней присутствуют языки к примеру ru.php, ua.php, en.php
ну и вот так выводить слова и прочее .lang('exit'). - Выход (Exit)
Создаем файл-библиотеку для работы с переводами
lang.class.php
<?php
class Lang {
const LANG_DIR = __DIR__."/langs/"; //папка где хранфятся все переводы
private $language = "ru"; //Язык (по сути своей папка в которой может лежать куча файлов с переводами разбитыми по некоей тематике
private $translationTable = []; //общая таблица переводов
public function __construct( $language = "ru") {
$this->setLanguage( $language );
}
/**
* Установка языка
* @param string $language Язык переводов
*/
public function setLanguage( $language = null ) {
if ( !is_null( $language ) && $this->getLanguage() != $language && ( realpath( self::LANG_DIR.$language ) !== false AND is_dir( realpath( self::LANG_DIR.$language ) ) ) ) {
$this->language = $language;
}
}
/**
* Возвращает текущий язык переводов
* @return string
*/
public function getLanguage() {
return $this->language;
}
/**
* Возвращает текст перевода из файла $category
* @param string $category Имя файла (без .php) в папке переводов и в подпапке языка переводов
* @param string $message Ключ в ассоциативном массиве файла переводов
* @param array $params Ассоциативный массив позволяющий использовать внутри текста перевода подставноку значений по алиасам
* @return string
*/
public function t( $category, $message, $params = [] ) {
if ( !isset( $translationsTable[$category] ) && file_exists( self::LANG_DIR.$this->getLanguage()."/".$category.".php" ) ) {
$translationsTable[$category] = @require_once( self::LANG_DIR.$this->getLanguage()."/".$category.".php" );
}
$result = ( is_array( $translationsTable[$category] ) && isset( $translationsTable[$category][ $message] ) ? $translationsTable[$category][ $message] : $message );
foreach( $params as $key => $value ) {
$result = ( mb_substr( $key, 0, 1 ) == "@" ? preg_replace("/\\".$key."/", $value, $result) : $result );
}
return $result;
}
}
Где-то в папке проекта создаем папку langs
и в ней две подпапки ru
и de
(не забудьте в lang.class.php
поправить LANG_DIR
путь к этим папкам) - это для теста. Если Вам нужны другие языки - создайте соответствующие папки.
В каждой из них создаем два файла
login.php (для DE)
<?php
return array(
'Account disabled' => 'Account deaktiviert',
'Incorrect username or password' => 'Falscher Benutzername oder falsches Passwort',
);
users.php (для DE)
<?php
return array(
'Please, fill the field `username`' => 'Bitte füllen Sie das Feld `Benutzername` aus',
'Username `@username` is invalid' => 'Benutzername `@username` ist ungültig',
);
И тоже самое для RU
login.php (для RU)
<?php
return array(
'Account disabled' => 'Аккаунт пользовател отключен',
'Incorrect username or password' => 'неверное имя пользователя или пароль',
);
users.php (для RU)
<?php
return array(
'Please, fill the field `username`' => 'Пожалуйста заполните поле `имя пользователя`',
'Username `@username` is invalid' => 'Имя пользователя `@username` некорректно',
);
Ну и собственно создаем файл для проверки как работает наш класс с переводами
test.php
<?php
//Подключаем файл-библиотеку с классом переводов
include_once("lang.class.php" );
//создаем класс и сразу переключаемся на немецкий т.к по-умолчанию у нас язык русский
$lang = new Lang("de");
//Выводим перевод сообщения "Account disabled" предположим для страницы авторизации на текущем языке
echo $lang->getLanguage()."> ".$lang->t('login','Account disabled')."\n";
//Переключаем текущий язык на русский
$lang->setlanguage("ru");
//Выводим сообщение с подставлением параметра внутрь текста перевода уже из другого файла переводов
echo $lang->getLanguage()."> ".$lang->t('users', 'Username `@username` is invalid', ['@username' => 'vasya_pupkin'])."\n";
Примерно так работают классы переводов во всех популярных php
-фреймворках, на которые я Вам и советую перейти дабы не мучиться с написанием собственных велосипедов.
Надеюсь я Вам помог.
P.S Для удобства можете переделать вызовы функций класса на статические (если Вам лень создавать экземпляр класса) :)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
пните меня в нужном направлении, например есть какой-либо сериал, сериал как принято делится на сезоны а сезоны в свою очередь на серииЗадача...
Столкнулся с тем, что нужно кастомизировать страничку, которая открывается при переходе на товар(Single-Product)Подскажите, пожалуйста, как правильно...