Как отладка gettext не работает в PHP?

Я пытаюсь использовать расширение php gettext в php 5.5 (на сервере win2008, используя IIS7). Я делаю это:

<?php

$locale = "es";
if (isSet($_GET["locale"])) $locale = $_GET["locale"];
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", "./locale");
textdomain("messages");

echo gettext("Hello world");

?>

С этой структурой папок на месте:

locale/es/LC_MESSAGES/messages.mo

Но он всегда возвращает мир Hello, а не правильный перевод, который на данный момент (на основе моего отсутствия испанских навыков) заключается в файле messages.po:

msgid ""
msgstr ""
"Project-Id-Version: TestXlations\n"
"POT-Creation-Date: 2014-04-19 08:15-0500\n"
"PO-Revision-Date: 2014-04-19 09:18-0500\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.6.3\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SearchPath-0: c:/dev\n"

msgid "Hello world"
msgstr "Hola World"

Это не выполняется из строки cmd и через IIS. Поэтому я вижу вызов gettext и т.д. И выполняю его, но он не читает файл перевода. как я могу отладить это дальше? даже если удалить файл перевода, я получаю такое же поведение.

Ответ 1

Вы должны проверить возвращаемые значения и знать, какая функция не выполнена. Он не специфичен для i18n, но полезен для любых сценариев PHP или для отладки любого языка программирования.

<?php
$locale = 'es';
if (isset($_GET["locale"])) $locale = $_GET["locale"];

$domain = 'messages';

$results = putenv("LC_ALL=$locale");
if (!$results) {
    exit ('putenv failed');
}

// http://msdn.microsoft.com/en-us/library/39cwe7zf%28v=vs.100%29.aspx
$results = setlocale(LC_ALL, $locale, 'spanish');
if (!$results) {
    exit ('setlocale failed: locale function is not available on this platform, or the given local does not exist in this environment');
}

$results = bindtextdomain($domain, "./locales");
echo 'new text domain is set: ' . $results. "\n";

$results = textdomain($domain);
echo 'current message domain is set: ' . $results. "\n";

$results = gettext("Hello world");
if ($results === "Hello world") {
    echo "Original English was returned. Something wrong\n";
}
echo $results . "\n";

Ответ 2

Вы находите "es" в выводе "locale -a"? Если нет, вам нужно запустить следующую команду.

 sudo locale-gen es

Ответ 3

Имея ту же проблему в Linux, я пришел к такому выводу: даже если вы предоставляете свои собственные файлы *.mo для вашего проекта, сама локаль (и) должна быть известна операционной системе.

Установка запрошенной локали на системном уровне устранила проблему для меня.

Смотрите: locale-gen

Это может не помочь с отладкой gettext, но, по крайней мере, вы можете попробовать это.

Ответ 4

В соответствии с незнанием того, какой языковой пакет использовать в ОС, к счастью функция setlocale() позволяет использовать массив. В соответствии с Документы PHP:

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

При этом вы можете выкопать, чтобы узнать местность, на которую ОС возвращается, путем проверки набора после:

$locales = array( "fr_FR", "fr_FR.UTF-8", "fr_FR.utf8", "fr-FR" );

if (( $setTo = setlocale( LC_ALL, $locales )) === FALSE )
{
    echo "Unable to set a locale that the OS recognises.";
    return false;
}
else
{
    echo "Set LC_ALL to " . $setTo; //echos fr_FR.utf8
    return true;
}

$setTo будет предоставлено значение $locales, которое было успешным. Это может быть полезно при определении того, какой язык для записи .po for.

Как написано в моих комментариях, у меня была проблема, когда я не выполнял этот setlocale() в верхней части каждого script каждого запроса страницы, так как вам нужно будет сохранить выбор языка по сеансу или значение базы данных. Как я наивно считал, что он был установлен, он был установлен навсегда!

Ответ 5

Это немного старый вопрос, но здесь идет этот ответ в надежде быть полезным для кого-то.

Попробуйте изменить LC_ALL на LANG в функции putenv, из этого:

$results = putenv("LC_ALL=$locale");

:

$results = putenv("LANG=$locale");

В маке были заданы проблемы с LC_ALL и, вероятно, это то же самое здесь.

Также проверьте этот ответ в других случаях fooobar.com/questions/299980/...

Надеюсь, что это поможет!

Ответ 6

Попробуйте установить также env vars LC_LANG и LC_LANGUAGE не только LC_ALL:

putenv("LC_ALL=$locale");
putenv("LC_LANG=$locale");
putenv("LC_LANGUAGE=$locale");