可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
i am trying to use the php gettext extension in php 5.5 (on win2008 server, using IIS7). I am doing this:
<?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");
?>
With this folder structure in place:
locale/es/LC_MESSAGES/messages.mo
But it always just returns Hello world and not the correct translation which for now (based on my lack of spanish skills) is this in the messages.po file:
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"
This fails from the cmd line and via IIS. So i it's seeing the gettext call, etc and executing it but it's not reading the translation file. how can i debug this further? even if remove the translation file, i get the same behavior.
回答1:
You should check returned values and know which function failed. It is not i18n specific but useful for any PHP scripts, or any programming language debugging.
<?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:
Do you find "es" in the output of 'locale -a' ? If not then you need to run the following command.
sudo locale-gen es
回答3:
Having the same problem on Linux, I came to this conclusion:
even if you provide your own *.mo files for your project, the locale itself (es) must be known to the operating system.
Installing the requested locale at a system level fixed the problem for me.
See: locale-gen
It might not help with actually debugging gettext, but at least it's something you can try.
回答4:
As per not knowing which language pack to use on the OS, thankfully the setlocale()
function allows for an array. As per the PHP Docs:
"If locale is an array or followed by additional parameters then each array element or parameter is tried to be set as new locale until success. This is useful if a locale is known under different names on different systems or for providing a fallback for a possibly not available locale"
With this, you can dig to find out locale the OS is falling back to by checking the set after:
$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
will be provided with the $locales
value that was successful. This might be helpful when finding which locale to write a .po
for.
As per written in my comments, I had the issue where I was not performing this setlocale()
at the top of each script of every page request, as you'll need to retain the user's choice of language by session or database value. As I believed naively once it was set, it was set forever!
回答5:
It's a bit old question but here goes this answer in the hope of being useful for someone.
Try changing LC_ALL
to LANG
in the putenv
function, from this:
$results = putenv("LC_ALL=$locale");
to this:
$results = putenv("LANG=$locale");
In the mac it was given problems with LC_ALL and probably it the same here .
Also check this answer in other cases
https://stackoverflow.com/a/3535866/6628843
Hope it helps!
回答6:
Try to set also env vars LC_LANG
and LC_LANGUAGE
not only the LC_ALL
:
putenv("LC_ALL=$locale");
putenv("LC_LANG=$locale");
putenv("LC_LANGUAGE=$locale");