PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links | my php.net 
search for in the  
<unregister_tick_functionbind_textdomain_codeset>
view the version of this page
Last updated: Sat, 19 Apr 2003

XXXV. GNU Gettext

Die gettext Funktionen implementieren eine NLS (Native Language Support) API, welche zur Internationalisierung von PHP Anwendungen genutzt werden kann. Eine ausf�hrliche Erkl�rung der folgenden Funktionen ist in der GNU gettext Dokumentation zu finden.

Inhaltsverzeichnis
bind_textdomain_codeset --  Specify the character encoding in which the messages from the DOMAIN message catalog will be returned
bindtextdomain -- Setzt den Pfad f�r einen Textbereich
dcgettext -- Setzt den Textbereich f�r eine Abfrage neu
dcngettext -- Plural version of dcgettext
dgettext -- Setzt den Textbereich f�r eine Abfrage neu
dngettext -- Plural version of dgettext
gettext -- Liefert eine �bersetzung f�r den aktuellen Textbereich
ngettext -- Plural version of gettext
textdomain -- Setzt den Standardbereich


User Contributed Notes
GNU Gettext
add a note
ilya at vtrails dot com
09-Jul-2000 02:01

For all the confused folks: gettext is GNU's project, it's main purpose is to allow easy internationalization of programs (that is, translation of messages to other languages). Check
for details about the library itself. Also, read gettext description in this manual to see what it has to do with PHP.
Basicly, instead of printing your messages in the usual way in PHP code, you can use gettext calls to substitute messages in other languages on the fly

11-Jul-2001 12:40
It is probably obvious to many of you,  but I thought it was worth mentioning that the domain is the name of the .mo files that contain the string catalogue (without the extension).

so if you have a catalogue myPage.mo for each page in './locale/lg/LC_MESSAGE' and some generic catalogues (e.g. errorMsg.mo) in '/global/locale/lg/LC_MESSAGE', you can do

bindTextDomain("$myPage", './locale');
bindTextDomain('errorMsg','/global/locale' );
textDomain('myPage');
print(getText('Welcome'));
/.../
if($err)printf(dGetText('errorMsg','you have an error here'));

Ivan

12-Jul-2001 11:59
To get xgettext working with my php code I had to change simple quotes to double quites in my previous example :

print(getText("Welcome"));
/.../
if($err)printf(dGetText("errorMsg","you have an error here"));

I guess that's because strings can not be simple-quoted in C. However I think it is good practice to do as if it was a simple quote, because you do not want to interpolate a string that will end in the catalogue.

Ivan

Michele dot Manzato at verona dot miz dot it
14-Sep-2001 10:52

Gettext is great, but there are a few caveats you have to consider in order to make it work. Unfortunately the gettext docs isn't so plain and clear...

The .mo file created with the gettext utilities must be:

[bindtextdomain's dir]/[language]/LC_MESSAGES/[domain].mo

otherwise gettext() function will fail to find it (this is true in win32, don't know about Un*ces). By the way you don't get any error message, the strings will simply remain untranslated.

Second, you must make sure which is the current directory if you use a relative path in bindtextdomain. On some systems the script directory isn't the current directory, so you have to chdir() there.

Then, of course, make sure that the appropriate gettext extension are loaded by PHP by looking at the php configuration file.

Here is some sample code:

// Change to the script directory
$path = dirname(getenv(PATH_TRANSLATED));
chdir($path);

// Set the language as 'it'
$language = 'it';
putenv("LANG=$language");
setlocale(LC_ALL, $language);

// Set the text domain as 'mydomain'
$domain = 'mydomain';
bindtextdomain("$domain", "./locale");
textdomain("$domain");

// The .mo file searched is:
// ./locale/it/LC_MESSAGES/mydomain.mo

echo gettext("Hello world!");

Have fun!
Michele

hace_x at yahoo dot com
15-Nov-2001 12:40

I had alot of problems to get gettext() to work on my windows2000-php webserver. The following will give those windows-php users something to hold on to:

Note the way you have to use slashes for the bindtextdomain command:

For a 'greetings' domain:

bindtextdomain ("greetings", ".\includes\translations");

(so, TWO slashes instead of one between the folder-names!)

ALSO, I had to change the filename to be 'greetings.mo': This was NOT clear from all the gnu-pages I read. I had named those files: nl.mo (for dutch) and fr.mo (for french etcetera).

I provide my code and folder-structure here for other windows-users:

<?
Header("Content-type: text/plain");
// Bind a domain to directory
// Gettext uses domains to know what directories to
// search for translations to messages passed to gettext

bindtextdomain ("greetings", "./includes/translations"); // Set the current domain that gettext will use
textdomain ('greetings'); # Make an array

# Use the ISO two-letter codes as keys
# Use the language names as values
$iso_codes = array (
  'en'=>'English',
'fr'=>'French',
  'it'=>'Italian',
 'pt'=>'Portuguese',
  'es'=>'Spanish',
'nl'=>'Nederlands'
);
foreach ($iso_codes as $iso_code => $language) {
  # Set the LANGUAGE environment variable to the desired language
  putenv ('LANG='.$iso_code); # Print out the language name and greeting
# Filter the greeting through gettext

printf ("%12s: %s\n", $language, gettext("str_hello")) & "\n";

}
?>

In the windows-webfolder I have the following directory-structure:

==
includes\translations
includes\translationsen
includes\translations\en\LC_MESSAGES
includes\translations\en\LC_MESSAGES\greetings.po
includes\translations\nl\
includes\translations\nl\LC_MESSAGES
includes\translations\nl\LC_MESSAGES\greetings.mo
\includes\translations\nl\LC_MESSAGES\greetings.po
===

To get this working you will need a greetings.po file like this:

(this one is in the 'nl' subdir for dutch language):
===
msgid ""
msgstr ""
"Project-Id-Version: n"
"POT-Creation-Date: n"
"PO-Revision-Date: 2001-11-14 17:11+0100n"
"Last-Translator: Melle Koning <[email protected]>n"
"Language-Team: <>n"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=utf-8n"
"Content-Transfer-Encoding: 8bitn"

msgid "str_hello"
msgstr "hallo"
===

and you have to 'compile' this .po file to a .mo file with the following command-line (go to windows 'command prompt'):

==
msgfmt -o greetings.mo greetings.po
==

To get msgfmt working on your windows machine, you will need to have libiconv.dll, libintl.dll and msgfmt.exe in your path. What I did was put these three files in a new c:utils folder and than run the command:
path=%path%;c:utils

I hope this helps some windows-users like me to get gettext() to work on their systems.......

Cheers,
Melle
[email protected]

mgvNOSPAM at fx dot ro
05-Jun-2002 02:47

If you're as clueless as I am, please note the following:
1. Although most comments list setlocal() in the code, that's not actually required for translations - read the docs under "string functions" for details (also, the official gettext() examples don't include it);
2. hace_x's example is really cool, except you need to know that all "n"'s at the end of his strings should have a backslash before - they're actually EOL characters, but they somehow got messed up and I needed two hours to find that out...

php at dynaperl dot com
25-Jun-2002 01:49

�f you install from SuSE Dist. you need glibc-locale.rpm to let gettext work.

mfg ralph.

ywliu atsign hotmail com
09-Jul-2002 04:39

Hello,

For users with Red Hat GNU/Linux (at least 6.2) to use gettext, I'd like to make some notes here :

1. Calling setlocale() is necessary, where calling putenv('LANG=xx_YY') or putenv('LC_ALL=xx_YY') is not.

2. The country/language code should be in the "language_country" form,such as, "en_US" or "fr_FR", or any entry in /usr/share/locale/locale.aliase . The simple ISO two-letter code, such as "en" , is not valid. You can examine the return value of setlocale to see if the locale setting succeeds.

This took me several hours to debug. I hope my experience can save you some time.

This may apply to other Linux distributions or *BSD systems. I don't know. I hope this helps.

Yen-Wei Liu

flaimo at gmx dot net
28-Dec-2002 04:20

since my provider doesn't support gettext, i've written a language + translation class. if you have the same problem you could take a look at it at
yledoare at free dot fr
15-Jan-2003 02:32

Corrections to "hace_x at yahoo dot com" message.

Note : The backslash have been removed in the greetings.po sample code (before the n characters at end of lines).

Same thing for ".includestranslations" to move into "./includes/translations" in php sample.

I used mingw () with gettext package () to make it work under WinXp.

I uncoment also "extension=php_gettext.dll" in php.ini (I am using easy php 1.6.0.0)

Here is my conv.bat to generate french translation :

set path=c:\mingw\bin
msgfmt -v -o greetings.mo greetings.po
pause

That's all !

Yann Le Doar�, Brest, France

Eneko Lacunza enlar at enlar dot net
16-Jan-2003 03:20

Some tips from my Red Hat Linux 7.3 system.

It didn't work for me until I set a full locale (i.e. es_ES) with setlocale.

I was trying with Michele Manzato's example (thank you!), but as it sets the language without the country, it was failing for me. Here is the example "fixed" with full locale:

// Change to script directory
// (Not needed in RH 7.3)
$path = dirname(getenv(PATH_TRANSLATED));
chdir($path);

// Set the language as full locale 'es_ES'
$language = 'es_ES';
putenv("LANG=$language");
setlocale(LC_ALL, $language);

// Set the text domain as 'mydomain'
$domain = 'mydomain';
bindtextdomain("$domain", "./locale");
textdomain("$domain");

// The .mo file searched is:
// ./locale/es_ES/LC_MESSAGES/mydomain.mo
// or if previous one doesn't exist:
// ./locale/es/LC_MESSAGES/mydomain.mo

echo gettext("Hello world!");

Hope this helps!
Eneko.

php at zpod dot ca
30-Jan-2003 02:24

For those of you just trying to get a script working and your provider doesn't support gettext, you can bypass the international stuff by adding this:

function _($str) {
   return $str;
}

zw at matfyz dot cz
05-Feb-2003 05:38

There is a nice tutorial on using gettext with php
technik at part2part dot com
18-Feb-2003 01:12

(german below)

gettext do not work correct, e.g. it do not translate.

I lost many times on my S.u.S.E. System but I think, this is not a problem by S.u.S:E: only.

You must set de_DE or en_GB or xx_XX not de or en or xx in function setlocale.

A call strace my_gettext_program_in_C show me, en or de do not work in C and in php also.

For an translation from non-English  to English it is an good idea to take a look in /usr/share/locale/locale.alias
If you don't find en_GB it is nessesery to add this.

German:

Gettexet funktioniert nicht wie gewollt, dh. die Funktion gibt keine Fehler aus, �bersetzt aber auch nicht.

Nach viel probieren und experimentieren fand ich die L�sung. Es reicht nicht einfach nur de in setlocale zu verwenden. Es ist notwendig de_DE oder en_GB zu benutzten.

Falls die �bersetztung von Deutsch nach Englisch nicht funktioniert, hilft eine �berpr�fung von /usr/share/locale/locale.alias vielleicht weiter. Fehlt da en_GB wird es nicht gehen. Also erg�nzen.

robert at klugher dot com
25-Feb-2003 12:24

One trick I found after HOURS of tries :

when you use the setlocale(), PHP will use the locale info it will find in, for example, /usr/share/locale to set the language info for LC_ALL, LC_MESSAGES, ...

You can check the exact info it will use by using putenv() with LANG=.... and looking at the return value of setlocale(LC_ALL, ""). The language value your gettext function will use to look for your translation file is the one given for LC_MESSAGES.

Example :

I was setting the LANG as fr_BE, and placed the translation file in dirxxx/locale/fr_BE/LC_MESSAGES/...
As it was locale info in my system for fr_BE but NOT LC_MESSAGES, PHP choosed to use the LC_MESSAGES settings for fr_FR instead and then, was looking for a translation file in dirxxx/locale/fr_FR/LC_MESSAGES/..., which wasn't found of course.

So, just make sure to look at the return value of setlocale to see what language value is associated to LC_MESSAGES and, then, to know in which subdirectory the translation file will be looked for by gettext.

Robert

robert at klugher dot com
25-Feb-2003 04:03

Sorry, one more info :

the previous post is especially interesting when you have values set on the server for some of the LC_... then, setlocale() output gives you all the LC_... with their value.

BUT do not forget that the priority order for gettext is:

LANGUAGE
LC_ALL
LC_MESSAGES
LANG

Then, if ever you script always translate to the same language, check the value of LANGUAGE ...

kleinerwurm at gmx dot net
03-Apr-2003 11:59

Addition to 'Note to Win32 Users' above: gnu_gettext.dll needs iconv.dll besides libintl-1.dll (is also distributed along, but not mentioned anywhere else)!
anders at frostad dot org
04-Apr-2003 09:54

I've had a few problems with gettext where some strings get
translated, while others don't. Seems a little random what gets
translated or not.

Anyway, restarting apache after compiling the .mo file solves it...

Daniel Garcia
29-Apr-2003 08:04

For win32 users: besides copying the DLLs mentioned in the documentation, I had to uncomment the line:

extension=php_gettext.dll

in php.ini, and restart apache. It's probably obvious, but I could not find it in the docs.

cheers !

add a note

<unregister_tick_functionbind_textdomain_codeset>
 Last updated: Sat, 19 Apr 2003
show source | credits | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: /
Last updated: Wed May 14 01:12:44 2003 CEST