Search code examples
phpdebiangettextphp-gettext

php gettext translation not working on Debian


(I've seen the other questions, but their answers didn't help me)

I have an application that uses php gettext for translations, and has been working for years on OSX and FreeBSD. When I tried to port it to Debian 7.6 32bit (Linux debian32bit 3.2.0-4-686-pae #1 SMP Debian 3.2.60-1+deb7u3 i686 GNU/Linux), everything works, except translations. I've got the problem down to a CLI one-liner:

env LANG=nl_NL.UTF-8 php -r 'var_dump(bindtextdomain("foo","locale")); var_dump(textdomain("foo")); var_dump(getenv("LANG")); var_dump(_("low"));'

locale/nl/LC_MESSAGES/foo.mo contains the Dutch translation of low, ie. laag

On OSX Maverick:

string(34) "/Users/foobar/workspace/bar/locale"
string(5) "foo"
string(11) "nl_NL.UTF-8"
string(4) "laag" <-- Success!

On FreeBSD 10 64bit:

string(24) "/usr/local/foobar/locale"
string(5) "foo"
string(11) "nl_NL.UTF-8"
string(4) "laag" <-- Success!

However, on Debian 7:

string(19) "/home/foobar/locale"
string(5) "foo"
string(11) "nl_NL.UTF-8"
string(3) "low" <-- Failure!

php-gettext is installed:

$ php -i | egrep -i 'PHP version|gettext'
PHP Version => 5.4.4-14+deb7u14
gettext
GetText Support => enabled

locale -a gives:

C
C.UTF-8
en_US.utf8
nl_NL.utf8
POSIX

So I tried nl_NL.utf8 instead of nl_NL.UTF-8: same result.

I tried putting the foo.mo file under locale/nl_NL/LC_MESSAGES, same result.

I tried to use the absolute path for locale instead of the path relative path to the current working directory, same result.

I'm at a loss here. Any suggestions on how to proceed?


Solution

  • Turns out I didn't spot the environment variable LANGUAGE, which has precedence over LANG and was set on my Debian machine, but not on the others.

    From the gettext documentation:

    When a program looks up locale dependent values, it does this according to the following environment variables, in priority order:

    1. LANGUAGE
    2. LC_ALL
    3. LC_xxx, according to selected locale category: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES, ...
    4. LANG

    Also, in my minimal example, setlocale must be called to get it to work the same on all machines. (I did that in my original code, but somehow it wasn't needed to get gettext to work on my other machines, so I left it out.)

    So, in the end, the following works on all machines:

    php -r 'var_dump(putenv("LANGUAGE=nl_NL.UTF-8")); var_dump(bindtextdomain("foo","locale")); var_dump(textdomain("foo")); var_dump(setlocale(LC_ALL,"nl_NL.UTF-8")); var_dump(_("low"));'