Я помню, как несколько месяцев назад тестировал несколько тестов с gettext, и следующий код работал отлично:
putenv('LANG=l33t');
putenv('LANGUAGE=l33t');
putenv('LC_MESSAGES=l33t');
if (defined('LC_MESSAGES')) // available if PHP was compiled with libintl
{
setlocale(LC_MESSAGES, 'l33t');
}
else
{
setlocale(LC_ALL, 'l33t');
}
bindtextdomain('default', './locale'); // ./locale/l33t/LC_MESSAGES/default.mo
bind_textdomain_codeset('default', 'UTF-8');
textdomain('default');
echo _('Hello World!'); // h3110 w0r1d!
Это работало отлично (под Windows XP и CentOS, если я правильно помню), что было хорошо, потому что я мог использовать произвольные "локали", не беспокоясь о том, были ли они установлены в системе или нет. Однако, похоже, это больше не работает, мне интересно, почему...
Red Hat + PHP 5.2.11:
Я могу переключаться назад и вперед из разных локалей, и переводы отображают соответствие, пока вызов setlocale()
не возвращает false (если локаль доступна/установлена в системе).
Это не идеально (было бы здорово, если бы я мог просто указать gettext в любой произвольный каталог переводов без проверки на наличие локали), но это приемлемо. В дальнейшем я проведу еще несколько тестов.
Windows 7 + PHP 5.3.1 (XAMPP):
setlocale()
всегда возвращает false (даже при использовании LC_ALL
вместо LC_MESSAGES
), если я не использую какой-либо допустимый локаль Windows, например eng
, deu
или ptg
- в этом случае локаль кажется для правильной установки, но переводы все еще не отображаются. Я не могу проверить прямо сейчас, потому что у меня открыто несколько вкладок, но я думаю, что самый первый вызов этого script дает правильный перевод (перезапуск Apache не будет делать трюк).
Я не уверен, связано ли это с PHP Bug # 49349. Я проверю это на пару часов.
Можно ли использовать расширение gettext (а не чистые реализации PHP, такие как php-gettext или Zend Translate Adapter) надежно в разных операционных системах (возможно, с пользовательскими локалями, такими как l33t
)?
Кроме того, абсолютно необходимо использовать setlocale(LC_ALL, ...)
? Я предпочел бы оставить настройки TIME
, NUMERIC
и MONETARY
(специально) локали нетронутыми (по умолчанию для языкового стандарта POSIX
).
У меня была идея... Можно ли вызвать setlocale()
с очень распространенной локалью (например, C
, POSIX
или en_US
) и указать язык через домен? Что-то вроде этого:
/lang/C/LC_MESSAGES/domain.pt.mo
/lang/C/LC_MESSAGES/domain.de.mo
/lang/C/LC_MESSAGES/domain.en.mo
/lang/C/LC_MESSAGES/domain2.pt.mo
/lang/C/LC_MESSAGES/domain2.de.mo
/lang/C/LC_MESSAGES/domain2.en.mo
Будет ли это работать на * nix и Windows plataforms без проблем?