Getting gettext to work in Apache on windows

Gnu gettext is a widely used translation system, used to translate software projects and make them available in different languages. Many big web projects use it, like WordPress for example. It works well and is rather easy to use, for both programmers and translators (except for the fact that you need to restart your http server every time the translation files change..). Using it also eliminates any need to write custom translation mechanisms yourself.

But there is a drawback for PHP developers, working on windows machines, who want to use gettext: you can’t change locale on Windows (not with the standard methods that is).

On Linux servers (or any other servers apart windows), the way to do it is this:

setlocale(LC_MESSAGES, “en_US”);

After you do this, the gettext subsystem (which you must use to translate all your texts), will know which of the translation files to use.

However, this doesn’t work on windows (LC_MESSAGES is an undefined constant on windows machines, and defining it to contain the same value as it does on Linux machines, doesn’t do any good).

But, as for most problems, a bit of Googling revealed a solution. The correct way to set locality on windows is this:


Now, of course, LC_ALL is not the same as LC_MESSAGES. LC_ALL means that more things will be affected by your locality setting, like formatted string output from strftime() or string comparison by strcoll(). However, i’ve never used those :) For a more detailed explanation of LC_* constants look at PHP setlocale manual.

In order to make sure, that locality changes correctly on both Linux and windows machines, you can use this:

$locality = 'en_US'; // locality should be determined here
if (defined('LC_MESSAGES')) {
    setlocale(LC_MESSAGES, $locality); // Linux
} else {
    putenv("LC_ALL={$locality}"); // windows

This works perfectly for me.

A neat thing

IETester is an incredible piece of software, that lets you run several instances of internet explorer 5.5, 6, 7 and 8 at the same time. It uses a tabbed interface, where every tab can be a different IE version. And it works! This wonderful tool is a really brilliant headache remover. I’ve tried several different solutions for having different versions of IE installed on one development machine (like Multiple IE and IE Collection) and this is by far the best one. If you are a web developer, you really should check it out.

1 Star2 Stars3 Stars4 Stars5 Stars (5 votes, average: 3.00 out of 5)

5 responses to “Getting gettext to work in Apache on windows”

  1. Martin

    It seem’s, that gettext with virtual server on Windows doesn’t work. If I install it to localhost all thinks work well, on my virtual server, gettext do not translate anything!

  2. Jose Miguel

    John, are you solved this issue? Happens to me exactly the same as you.

  3. James

    I also found that only putenv is required on windows, but am running into the problem where gettext only works intermittantly.
    You can refresh the page 20 times, and it will work sometimes, and the next time it will come back with the default language.

    Have been googling all day but have yet to find a solution.


  4. John

    I have the same problem with my xampp server in Windows Vista. Gettext does not work properly.

    The problem is that I have this code running in xampp under Widnows Vista Home:

    Untitled Document

    setlocale(LC_ALL, $language);
    bindtextdomain("messages", "./locale");
    print "”._(“hi! This website is written in English.”).”\n”;

    and no matter what string I set the variable $language with that gettext will always look for a translation in the folder locale\es_ES\LC_MESSAGES whether the language is Spanish (es_ES) or not. For example, in the above code, gettext will not look for the French translation as it should in
    locale\fr_FR\LC_MESSAGES but it will look for the translation into the folder corresponding to Spanish language, that is to say, locale\es_ES\LC_MESSAGES.

    Moreover, if gettext does not find the folder locale\es_ES\LC_MESSAGES then
    it will display the string in the original language(English) even if $language equals “fr_FR” and at the same time there is a locale\fr_FR\LC_MESSAGES folder created and the corresponding and messages.po files created in this folder.

    I made sure that I re-run Apache and MySql under Xampp whenever I change anything in the code but it keeps having this behaviour anyways.

    Do you have any idea about why only translations in .po files in the Spanish folder locale\es_ES\LC_MESSAGES are considered and not those translations corresponding to other languages and other folders?

    Thanks in advance.

Leave a Reply