Самый эффективный способ создать языковой файл на PHP?

StackOverflow https://stackoverflow.com/questions/1414079

  •  06-07-2019
  •  | 
  •  

Вопрос

Вопросы обновляются вместо того, чтобы создавать новый вопрос...

Я действительно хочу предоставить несколько альтернативных языков, кроме английского, на моем сайте в социальной сети, который я создаю, это будет мой первый перевод на какой-либо язык, поэтому, пожалуйста, потерпите меня.
Я занимаюсь исследованиями, поэтому я внимателен и открыт для идей, и у меня уже есть много вопросов, вот они.

1)
Что означает i18n, я часто сталкиваюсь с этим, исследуя языковой перевод на SO?

2)
Большинство людей говорят, что используйте gettext - получить текст PHP имеет расширение или поддержку для него,
ну, я исследовал это, и у меня есть базовое представление об этом, насколько я могу судить, чтобы пройти этот путь, требуется много дополнительной работы,
Я имею в виду кодирование моего сайта для использования его функций, т.е.; _("привет, мир, я пока на английском") или же gettext ("привет, мир, я пока на английском") это не проблема, поскольку любой маршрут, по которому я пойду, потребует этого.
Но тогда вам нужно установить gettext на свой сервер и заставить его работать,
затем используйте какие-нибудь специальные редакторы для создания специальных файлов и их компиляции, я думаю?

Звучит как боль, я понимаю, что это должен быть лучший путь, хотя, кажется, все говорят, что это так.
Итак, может ли кто-нибудь сказать мне, почему именно этим путем следует идти?

3)
Мне действительно нравится простота этого подхода, просто создайте языковой массив и вызовите нужную вам фразу в функции, подобной приведенному ниже примеру , затем вы просто добавите файл с соответствующим языковым массивом.

Что я действительно хочу знать, так это будет ли это менее эффективный метод на сайте с высоким трафиком и довольно большим сайтом по сравнению с использованием gettext, и если да, то не могли бы вы объяснить, почему, пожалуйста?

<?PHP
//Have seperate language files for each language I add, this would be english file
function lang($phrase){
    static $lang = array(
        'NO_PHOTO' => 'No photo\'s available',
        'NEW_MEMBER' => 'This user is new'
    );
    return $lang[$phrase];
}
//Then in application where there is text from the site and not from users I would do something like this
echo lang('NO_PHOTO');  // No photo's available would show here
?>

* некоторый код, использованный из приведенного ниже ответа брайана Ривиса

Это было полезно?

Решение

Не изобретайте велосипед заново.Используйте, например, gettext - получить текст или Zend_Translate ( Зенд_трансляция ).

Другие советы

Вероятно, было бы лучше определить функцию, которая обрабатывает ваше языковое сопоставление.Таким образом, если вы делай если вы захотите изменить способ его работы позже, вам не придется просматривать сотни сценариев в поисках случаев, когда вы использовали $lang[...] и замените их чем-нибудь другим.

Что-то подобное сработало бы и было бы приятным и быстрым:

function lang($phrase){
    static $lang = array(
        'NO_PHOTO' => 'No photo\'s available',
        'NEW_MEMBER' => 'This user is new'
    );
    return $lang[$phrase];
}

Сделать конечно массив объявлен static внутри функции, чтобы она не перераспределялась при каждом вызове функции.Это особенно важно, когда $lang действительно большой.

Чтобы использовать его:

echo lang('NO_PHOTO');

Для работы с несколькими языками просто определите эту функцию в нескольких файлах (например en.php, fr.php, и т.д.) и require() подходящий для пользователя.

Это могло бы сработать лучше:

function _L($phrase){
static $_L = array(
    'NO_PHOTO' => 'No photo\'s available',
    'NEW_MEMBER' => 'This user is new'
);

     return (!array_key_exists($phrase,$_L)) ? $phrase : $_L[$phrase];
}

Это то, чем я сейчас пользуюсь.Если язык не найден, он вернет фразу, а не сообщение об ошибке.

Следует отметить, что массив может содержать не более ~65500 элементов.Должно быть достаточно, но ладно, просто говорю.

Вот некоторый код, который я использую для проверки языка пользователя:

<?php
function setSessionLanguageToDefault() {
    $ip=$_SERVER['REMOTE_ADDR'];
    $url='http://api.hostip.info/get_html.php?ip='.$ip;
    $data=file_get_contents($url);
    $s=explode (':',$data);
    $s2=explode('(',$s[1]);

    $country=str_replace(')','',substr($s2[1], 0, 3));

    if ($country=='us') {
        $country='en';
    }

    $country=strtolower(ereg_replace("[^A-Za-z0-9]", "", $country ));
    $_SESSION["_LANGUAGE"]=$country;
}

if (!isset($_SESSION["_LANGUAGE"])) {
    setSessionLanguageToDefault();
}

if (file_exists(APP_DIR.'/language/'.$_SESSION["_LANGUAGE"].'.php')) {
    include(APP_DIR.'/language/'.$_SESSION["_LANGUAGE"].'.php');
} else {
    include(APP_DIR.'/language/'.DEFAULT_LANG.'.php');
}

?>

Это еще не сделано, но я думаю, что это могло бы очень помочь.

Не пишите свой собственный языковой фреймворк.Использование gettext - получить текст.PHP имеет стандартный привязки который вы можете установить.

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

1) I18n - сокращение от "Интернационализация" и имеет некоторое сходство с I-eighteen-n.

2) По моему честному мнению, gettext - это пустая трата времени.

3) Ваш подход выглядит хорошо.На что вам следует обратить внимание, так это на языковые переменные.Тот самый Платформа сообщества WoltLab 2.0 реализует двустороннюю языковую систему.На этот раз существуют языковые переменные, которые сохраняются в базе данных и внутри шаблона, используется только имя переменной, которое затем будет заменено содержимым переменной на текущем языке (если доступно).Вторая часть системы предоставляет способ сохранения пользовательского контента на нескольких языках (требуется ввод на нескольких языках).

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

К сожалению, структура WCF устроена таким образом, что повторное использование кода вне фреймворка очень сложно, но вы можете использовать его как источник вдохновения.Сфера применения системы зависит исключительно от того, чего вы хотите достичь с помощью своего сайта.Если он будет большим, вам обязательно стоит взглянуть на систему WCF.Если он маленький немногие посвященные языковые файлы (de.php, en.php и т. д.), из которых необходимая для текущего языка в комплекте, сделаю.

К сожалению gettext - получить текст не работает хорошо и возникают проблемы в различных ситуациях, например, в разных ОС (Windows или Linux), и заставить его работать очень сложно.

Кроме того, это требует, чтобы вы установили множество переменных окружения и доменов, а это не имеет никакого смысла.

Если разработчик хочет просто получить перевод текста, он должен только указать путь к файлу .mo и получить перевод с помощью одной функции, такой как translate ("hello", "en_EN");С gettext это невозможно.

почему бы вам просто не сделать это в виде многомерного массива ... например, такого

<?php

$lang = array(
    'EN'=> array(
        'NO_PHOTO'=>'No photo\'s avaiable',
        'NEW_MEMBER'=>'This user is new',
    ),
    'MY'=> array(
        'NO_PHOTO'=>'Tiada gambar',
        'NEW_MEMBER'=>'Ini adalah pengguna baru',
    )
);

?>

Ты можешь это сделать:

class T {
const language = "English";
const home = "Home";
const blog = "Blog";
const forum = "Forum";
const contact = "Support";
}

У вас был бы такой файл для каждого языка.Чтобы использовать текст:

There is no place like <?=T::home?>.

Недостатком является то, что если вы добавляете новую константу, вам приходится делать это для каждый языковой файл.Если вы забудете один из них, ваша страница будет переведена на этот язык.Это немного неприятно, но это эффективно, поскольку для этого не нужно создавать большой ассоциативный массив и, возможно, значения даже будут встроены.

Возможно, доступ можно было бы улучшить, например:

class T {
    const home = "home";

    public static function _ ($name) {
        $value = @constant("self::$name");
        return $value ? $value : $name;
    }

    // Or maybe through an instance:
    public function __get ($name) {
        $value = @constant("self::$name");
        return $value ? $value : $name;
    }
}
echo "There is no " . T::_("place") . " like " . T::_("home");
$T = new T();
echo "There is no " . $T->place . " like " . $T->home;

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top