Я пытаюсь использовать расширение 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 world, а не правильный перевод, который на данный момент (основанный на моей нехватке испанских навыков) заключается в файле 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 и т. Д. И выполняю его, но он не читает файл перевода. как я могу отладить это дальше? даже если удалить файл перевода, я получаю такое же поведение.
Вы должны проверить возвращаемые значения и узнать, какая функция не удалась. Это не 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";
Имея ту же проблему в Linux, я пришел к такому выводу: даже если вы предоставляете свои собственные * .mo-файлы для своего проекта, сам язык (ы) должен быть известен операционной системе.
Установка запрошенной локали на системном уровне устранила проблему для меня.
См .: locale-gen
Это может не помочь в самом деле отладки gettext, но, по крайней мере, это то, что вы можете попробовать.
Вы находите «es» в выводе «locale -a»? Если нет, вам нужно запустить следующую команду.
sudo locale-gen es
Согласно незнанию того, какой языковой пакет использовать в ОС, к счастью функция 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()
в верхней части каждого скрипта каждого запроса страницы, так как вам нужно будет сохранить выбор языка пользователя по значению сеанса или базы данных. Как я наивно считал, что он был установлен, он был установлен навсегда!
Это немного старый вопрос, но здесь идет этот ответ в надежде быть полезным для кого-то.
Попробуйте изменить LC_ALL
на LANG
в функции putenv
, из этого:
$results = putenv("LC_ALL=$locale");
к этому:
$results = putenv("LANG=$locale");
В маке были заданы проблемы с LC_ALL и, вероятно, это то же самое здесь.
Также проверьте этот ответ в других случаях https://stackoverflow.com/a/3535866/6628843
Надеюсь, поможет!
Попробуйте установить также env vars LC_LANG
и LC_LANGUAGE
не только LC_ALL
:
putenv("LC_ALL=$locale"); putenv("LC_LANG=$locale"); putenv("LC_LANGUAGE=$locale");