How to debug gettext not working in PHP?

2019-01-25 05:37发布

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.

6条回答
贼婆χ
2楼-- · 2019-01-25 06:05

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!

查看更多
做自己的国王
3楼-- · 2019-01-25 06:14

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";
查看更多
Emotional °昔
4楼-- · 2019-01-25 06:16

Do you find "es" in the output of 'locale -a' ? If not then you need to run the following command.

 sudo locale-gen es
查看更多
Juvenile、少年°
5楼-- · 2019-01-25 06:24

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!

查看更多
We Are One
6楼-- · 2019-01-25 06:28

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");
查看更多
一夜七次
7楼-- · 2019-01-25 06:29

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.

查看更多
登录 后发表回答