gettext
(PHP 4, PHP 5, PHP 7, PHP 8)
gettext — 現在のドメインのメッセージを参照する
パラメータ
message
-
翻訳するメッセージ。
戻り値
翻訳テーブルに翻訳文字列が見つかった場合にその文字列、 あるいは見つからなかった場合に元の文字列を返します。
例
例1 gettext() のチェック
<?php
// ドイツ語に設定します
putenv('LC_ALL=de_DE');
setlocale(LC_ALL, 'de_DE');
// 変換テーブルの場所を指定します
bindtextdomain("myPHPApp", "./locale");
// ドメインを選択します
textdomain("myPHPApp");
// 翻訳内容は ./locale/de_DE/LC_MESSAGES/myPHPApp.mo から検索されます
// テストメッセージを出力します
echo gettext("Welcome to My PHP Application");
// あるいは、gettext() のかわりに _() も使用可能です
echo _("Have a nice day");
?>
注意
注意:
この関数のエイリアスとして、アンダースコア文字 '_' を使用することができます。
注意:
言語を設定するだけではだめなシステムもあり、 putenv() を使って正しいロケールを定義しなければなりません。
+add a note
User Contributed Notes 16 notes
kingjackal at gmail dot com ¶
6 years ago
If your PO/MO files make use of msgctxt (Context), you'll be frustrated to find that gettext(msgid) won't work as you might expect (even if msgid is unique).
In this case, you must use ASCII char 4 [EOT, End Of Text] glued between the msgctxt and msgid.
Example PO content:
msgctxt "Context"
msgid "Test string"
msgstr "Test translation"
msgid "Standard string"
msgstr "Standard translation"
The following will work:
<?php
gettext('Context' . "\004" . 'Test string');
gettext('Standard string');
?>
The following will NOT work:
<?php
gettext('Test string');
?>
ashi009 at gmail dot com ¶
12 years ago
The simplest way to by-pass gettext() cache, without restart apache nor change domain.
The fix is incredible simple, first create a dummy link to the locale folder where .mo files stored:
cd locale
ln -s . nocache
Then add one single line before bindtextdomain()
<?php
bindtextdomain('domain', './locale/nocache');
bindtextdomain('domain', './locale');
?>
Now the cache is forced to flush every time.
mikko dot rantalainen at peda dot net ¶
10 years ago
Worth noting is that gettext honors environment variables while selecting the language to use: http://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html
"When a program looks up locale dependent values, it does this according to the following environment variables, in priority order:
LANGUAGE
LC_ALL
LC_xxx, according to selected locale category: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES, ...
LANG
Variables whose value is set but is empty are ignored in this lookup. "
In short, if you have non-empty LANGUAGE, you may end up with unexpected localization strings. On the other hand, LANGUAGE can be used to define fallback language if some translation is missing.
surfchen at gmail dot com ¶
14 years ago
As of php 5.3, you can use the following code to get the preferred locale of the http agent.
<?php
$locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
?>
smerf(a)druid(d)if(d)uj(d)edu(d)pl ¶
19 years ago
Gettext translations are cached. If you change *.mo files your page may not be translated as expected. Here's simple workaround which does not require restarting webserver (I know, this is just a dirty hack):
<?php
function initialize_i18n($locale) {
putenv('LANG='.$locale);
setlocale(LC_ALL,"");
setlocale(LC_MESSAGES,$locale);
setlocale(LC_CTYPE,$locale);
$domains = glob($locales_root.'/'.$locale.'/LC_MESSAGES/messages-*.mo');
$current = basename($domains[0],'.mo');
$timestamp = preg_replace('{messages-}i','',$current);
bindtextdomain($current,$locales_root);
textdomain($current);
}
?>
to make this work you have to put your locale inside file messages-[unix_time].mo and use this name (without .mo) as your domain to fool caching mechanism (domain names differ)
msgfmt messages.po -o messages-`date +%s`.mo
for me this works fine (although this is not very elegant solution)
nayana at corp - gems dot com ¶
10 years ago
on OSX (10.9.3) and PHP (5.4.24) you need to use full local name including codeset
i.e. for German need to use de_DE.UTF-8 even setlocale returns success when used without .UTF-8 the lookups will not work.
iguy at ionsphere dot org ¶
23 years ago
Depending on the implementation of gettext used you might have to call the setlocale(LC_ALL, "") command.
So your example code would be
<?php
// Set language to German
putenv ("LANG=de");
// set the locale into the instance of gettext
setlocale(LC_ALL, "");
// Specify location of translation tables
bindtextdomain ("myPHPApp", "./locale");
// Choose domain
textdomain ("myPHPApp");
// Print a test message
print (gettext ("Welcome to My PHP Application"));
?>
NOTE: If setlocale returns NULL the LANG specified is invalid and "not supported".
jmeile at hotmail dot com ¶
10 years ago
I just wanted to say that gettext won't work on WAMP Server 2.4 / 64 Bit, see the thread I posted here:
Title: Gettext doesn't work on WAMP 64 Bits
http://forum.wampserver.com/read.php?2,120770,120770#msg-120770
I haven't tested with only apache 64 Bit, so, I don't know if the issue is related to apache or WAMP. Anyway, to make it work with WAMP, install the 32 Bit version of WAMP and only do this:
define('LOCALE_DIR', '<root_dir_of_your_po_files>'); //ie: C:/wamp/www/your_app/locale
$locale = '<your_locale>'; //ie: es_CO
$domain = 'your_gettext_domain'; //ie: messages
putenv('LC_ALL=' . $locale);
bindtextdomain($domain, LOCALE_DIR);
textdomain($domain);
echo _('<your_string>'; // ie: Hello world
"setlocale" nor setting the LANG, LANGUAGE, and LC_MESSAGES environment variables seems to be necessary under windows. I got it working by setting "LC_ALL" only.
ck at claudiokuenzler dot com ¶
4 years ago
If you come across a situation where the translation works fine on CLI but not on Apache, it may be caused by the Perl Apache module.
Basic translate.php:
<?php
// Set locale
putenv("LC_ALL=de_CH.UTF-8");
putenv("LANGUAGE=");
putenv("LANG=de_CH.UTF-8");
$res = setlocale(LC_ALL, 'de_CH.UTF-8', 'de_CH', 'de');
echo bindtextdomain("homepage", "./locale");
textdomain("homepage");
$results = gettext("My English Text");
if ($results === "My English Text") {
echo "Original English was returned. Something wrong\n";
} else {
echo $results;
}
?>
On the CLI the translation works:
$ php7.3 translate.php
Mein deutscher Text.
But not via Apache web server:
$ curl localhost/translate.php
Original English was returned. Something wrong
Disable Perl module and restart Apache:
# a2dismod perl
# systemctl restart apache2
And suddenly the translation works:
$ curl localhost/translate.php
Mein deutscher Text.
The exact reason for this behaviour is (as of right now) unknown to me.
jespersaNOSPAM at diku dot NO_SPAM dot dk ¶
22 years ago
There's a good tutorial to the GetText tools used with PHP at http://zez.org/article/articleview/42
The only modification I needed to do was to use the correct ISO-language/country-codes (don't know the ISO number) and call setlocale.
helloworld.php:
<?php
putenv("LC_ALL=da_DK"); // For danish/Denmark
setlocale(LC_ALL, "");
// ./locale/da/LC_MESSAGES holds the helloworld.mo file
bindtextdomain("helloworld", "./locale");
textdomain("helloworld");
print(gettext("Hello world!"));
?>
I had a lot of trouble getting this to work on Red Hat (Yellow Dog) Linux though.
naguissa at foroelectro dot net ¶
1 year ago
I was testing in a self-made NAS (Debian + OpenMediaVault) and I was not getting SOME translations.
Some translations worked OK but some others were ignored.
The problem was caused because I had not added that locales to my NAS locale:
1) Edit file /etc/locale.gen
2) Check if your locale is active (written and uncommented).
3) Execute "locale-gen" as root (or sudo).
So, in short, if you have a Linux system and your translations are ignore check if you have that locale active in your system.
saul dot dobney at notanant dot com ¶
5 years ago
putenv(...) can cause hidden problems when upgrading or moving between systems which are difficult to diagnose.
On one Linux server we had the following working perfectly with setlocale
putenv("LANG=$locale");
We switched servers and found gettext wouldn't work despite having all the same locale files and settings
The recommendation to switch to
putenv("LC_ALL=$locale");
didn't fix the problem.
However,
putenv("LANGUAGE=$locale");
did. So if you have problems, check all three settings.
bla at taxistop dot be ¶
13 years ago
For me it is sufficient to call setlocale() with a string like "nl_BE" as the second parameter, to make gettext() work. Just plain "nl" was not enough.
Ditto when using an environment variable like LANG: "en", "fr", "nl", "de" are not enough: I have to specify the country, too.
simen at nconel dot no ¶
12 years ago
gettext returns the headers from .mo files
if the message parameter is set to empty.
So if you are for example using Smarty blocks, make sure that the values given checks if the text has content or else your text will have a bunch of headers printing.
If you are putting a variable to the gettext, like so:
_($text);
you are better of making another function like this:
<?php
function __($text){
if(empty($text)) return "";
else gettext($text);
}
?>
florent at eledo dot com ¶
19 years ago
Take care when extracting the strings from the source files : if your source files are not encoded in ascii, then xgettext must be used with the --from-code option, and the generated .po file is *always* UTF-8 (even if you used a different --from-code charset).
The usage of gettext will not work later on strings which include non ascii caracters. For make it working, you have to translate the .po file to your proper charset with msgconv.
Example :
my source files are encoded in iso-8859-1
$ xgettext --from-code=iso-8859-1 -n *.php -o myapp.po
==> myapp.po is in UTF-8 (and generated .mo files will not work with gettext).
I have to convert it to iso-8859-1 before translating :
$ msgconv --to-code=iso-8859-1 myapp.po -o myapp.po
...and now translate the file.
adino at adino dot sk ¶
21 years ago
If you 're experiencing problems like gettext() is not working and you're getting translated text only occassionaly use: unset LANG before starting apache.
Next thing is that you have to restart apache after you 've changed .mo files because they're treated something like shared libraries.
I've only tested this with Linux (Sourcemage Linux distro, Mandrake) but it might be true for others as well.