Самый эффективный способ сделать языковой файл в PHP? - PullRequest
25 голосов
/ 12 сентября 2009

Вопросы обновлены вместо создания нового вопроса ...

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

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
?>

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

Ответы [ 8 ]

21 голосов
/ 12 сентября 2009

Вероятно, было бы лучше определить функцию, которая обрабатывает ваше языковое отображение. Таким образом, если вы do захотите изменить его работу позже, вам не придется искать сотни сценариев для случаев, когда вы использовали $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(), подходящую для пользователя.

10 голосов
/ 24 марта 2012

Это может работать лучше:

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');
}

?>

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

5 голосов
/ 12 сентября 2009

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

4 голосов
/ 12 сентября 2009

Не изобретай велосипед. Используйте, например, gettext или Zend_Translate .

1 голос
/ 02 октября 2017

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

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

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

1 голос
/ 12 января 2014

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

1) I18n означает «Интернационализация» и имеет некоторые сходства с I-восемнадцать-н.

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

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

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

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

0 голосов
/ 14 января 2018

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

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;

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

0 голосов
/ 12 сентября 2009

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

<?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',
    )
);

?>
...