Search code examples
phpinternationalizationgettextphp-gettext

php gettext directory structure on different environments


I'm using gettext for internationalization for my php files. I have two servers; a sandbox server and a release server. in sandbox server a directory like locale/LC_MESSAGES/en does not work and I should use locale/LC_MESSAGES/en_GB instead. But with "en_GB" it doesn't work on my production server and "en" works fine. for some languages like Portuguese I have pt_PT and pt_BR (Brazilian Portuguese). So I prefer to use the "A_B" structure.

I have no idea how gettext detects these folders. Is there a standard way to use the same folder structure?


Solution

  • If you're running your code on Linux, gettext works only with locales already installed on the OS. This means that if you set the locale to en_GB then if the only installed locale is en_GB.utf8 or en_US, then you don't get the translations.

    Try this on both of your environments and compare the results:

    locale -a
    

    It gives you a list of all the installed locales:

    en_US
    en_US.ISO8859-1
    en_US.ISO8859-15
    en_US.US-ASCII
    en_GB
    en_GB.utf8
    de_DE
    
    de_DE.utf8
    C
    POSIX
    

    Now you need to make sure that both of the environments have the same locales installed; If you need en_US.utf8, en_AU, and en_AU.utf8, you can create the missing locales based on an existing one (read localedef manpages to know the details):

    sudo localedef -c -i en_US -f UTF-8 en_US.utf8
    sudo localedef -c -i en_GB -f UTF-8 en_AU
    sudo localedef -c -i en_GB -f UTF-8 en_AU.utf8
    

    Also, what follows is the common best practice for using gettext on PHP:

    <?php
    
        // Set language to German
        putenv('LC_ALL=de_DE.utf8');
        setlocale(LC_ALL, 'de_DE.utf8');
    
        // Specify location of translation tables
        bindtextdomain("myPHPApp", "./locale");
    
        // Choose domain
        textdomain("myPHPApp");
    
        // Translation is looking for in ./locale/de_DE.utf8/LC_MESSAGES/myPHPApp.mo now
    
        // Print a test message
        echo gettext("Welcome to My PHP Application");
    
        // Or use the alias _() for gettext()
        echo _("Have a nice day");
    
    ?>
    

    Although you can simply drop the encoding and just de_DE, but it's a good practice to have the character set in the locale as in some specific cases you might need to support content in non-Unicode character sets. See below

    <?php
    
      // Set language to German written in Latin-1
      putenv('LC_ALL=de_DE.ISO8859-1');
      setlocale(LC_ALL, 'de_DE.ISO8859-1');
    
    ?>