PHP Doku:: Sucht einen Text in der aktuellen Domain - function.gettext.html

Verlauf / Chronik / History: (50) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzUnterstützung menschlicher Sprache und ZeichenkodierungGettextGettext-Funktionengettext

Ein Service von Reinhard Neidl - Webprogrammierung.

Gettext-Funktionen

<<dngettext

ngettext>>

gettext

(PHP 4, PHP 5)

gettextSucht einen Text in der aktuellen Domain

Beschreibung

string gettext ( string $message )

Sucht nach einer Mitteilung in der aktuellen Domain.

Parameter-Liste

message

Die zu übersetzende Mitteilung.

Rückgabewerte

Diese Funktion gibt einen übersetzten string zurück, falls einer in der Übersetzungstabelle gefunden wird, andernfalls den übergebenen Originalstring.

Beispiele

Beispiel #1 gettext()-Check

<?php
// Sprache auf Deutsch setzen
putenv('LC_ALL=de_DE');
setlocale(LC_ALL'de_DE');

// Angeben des Pfads der Ãœbersetzungstabellen
bindtextdomain("meinePHPApp""./locale");

// Domain auswählen
textdomain("meinePHPApp");

// Die Ãœbersetzung wird nun in ./locale/de_DE/LC_MESSAGES/meinePHPApp.mo gesucht

// Ausgeben des Test-Textes
echo gettext("Willkommen in meiner PHP-Applikation");

// Oder verwenden Sie den Alias _() für gettext()
echo _("Einen schönen Tag noch");
?>

Anmerkungen

Hinweis:

Sie können einen Unterstrich '_' als Alias für diese Funktion verwenden.

Hinweis:

Das reine Setzen einer Sprachangabe reicht bei einigen Systemen nicht aus. Daher sollte putenv() verwendet werden, um die aktuelle lokale Umgebung zu definieren.

Siehe auch


14 BenutzerBeiträge:
- Beiträge aktualisieren...
bla at taxistop dot be
6.01.2011 15:47
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.
surfchen at gmail dot com
4.03.2010 9:26
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']);
?>
mario dot ugedo at gmail dot com
10.09.2009 17:03
It's very important call a bind_textdomain_codeset(..) function.

Linux localhost 2.6.28-14-generic
Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.2

<?php
// Set language to Spanish
//setlocale(LC_ALL, 'es_ES'); // es_ES not in the server
setlocale(LC_MESSAGES, 'es_ES.utf8');
// run ok with LC_MESSAGES

// Specify location of translation tables
bindtextdomain("myAppPhp", "includes/locale");
bind_textdomain_codeset("myAppPhp", 'UTF-8');
// It's very important

// Choose domain
textdomain("myAppPhp");

// Translation is looking for in includes/locale/es_ES.utf8/LC_MESSAGESmyAppPhp.mo now
?>
<p><?=_("Welcome to My PHP Application");?></p>
<p><?=gettext("Have a nice day");?></p>

Ah, it's very important use locale should be install in the server
shell command "locale -a"
too see less /etc/locale.alias

The hosting server could be all locale installed

good luck
martinalex at tlonstruct.com
28.08.2009 15:25
On Windows (XP Pro SP3) it was not sufficient to set
the locale
<?php setlocale(LC_ALL, "de"); ?>

Prior to that I had to set the variable for the environment

<?php
putenv
("LC_ALL=de"); // german
setlocale(LC_ALL, "de");
?>

Without putenv no translation was found!
nonproffessional at clockworkgeek dot com
25.08.2009 15:46
If you want to have variables in your text to be translated the usual way would be with string formatting like so:
<?php
printf
(gettext("Hello %s!"), $world);
?>
This works because the string substitution is made after gettext performs. The human translator needs to be aware of what %s represents, when there are many variables in a line it can get confusing.

We can evaluate the string as PHP code instead of using string formatting:
<?php
eval('echo "' . addslashes(gettext('Hello $world!')) . '";');
?>
Notice the text to be translated is in single quotes so $world does not get evaluated too soon. Quotes in the translated text are escaped to prevent bad parsing.

Now the human translator will see $world which is more meaningful than "%s". He must be careful not to translate the variable name but leave it intact.
It is also easier to change the order in which variables are used instead of printf's arcane "%2$s". For advanced use the translator could take advantage of functions like ucwords().

The downside of this method is any PHP code can be evaluated which might be damaging. This is equivalent to an injection attack. Make sure to vet all translated text to prevent other code sneaking in.
daemonraco at yahoo dot com dot ar
24.04.2007 23:06
I had a problem like "adino at adino dot sk" said, so I did the unsetting of LANG ($ unset LANG), but it was not sufficient, I had to unset the environment variable LANGUAGE too.

I tried to do this using "sudo", but it didn't works, so I had to change to root using "su"

If you need to know, I use Musix (a sub-distro of Devia).

I hope this will help you, Seeya! ^__^'
vinaykuruvila at gmail dot com
3.03.2006 23:55
If like me, you are stuck with making a lot of code localizable, you have to go through all your php files and wrap all srings in _("string"). Here's an elisp function which can help you out.

This function enables you to highlight some text in an emacs buffer and make it a localizable string using the keyboard shortcut C-l (Ctrl and l). If the first character highlighted is " or ', then it assumes the text is in php-context and changes it to: _(HIGHLIGHTED_TEXT). Otherwise it assumes the text is in html-context and changes it to <?=_('HIGHLIGHTED_TEXT')?>

The shortcut C-k can be used for translating parts of php strings which contain html tabs. We dont want to translate the entire string including the tabs, so we highlight just the substring that needs to be translated and use C-k.

To use it, do either of:
Copy and paste the following code into your .emacs file. This would permanently associate the keyboard shortcut C-l with this function.
Save the code in a new file ending with the .el extension. Evaluate it using M-x eval-buffer. This makes the C-l keyboard shortcut only last for the current Emacs session.

Code
;author: Vinay Kuruvila March 01 2006
;updated to handle php strings containing html tabs

;makes the text starting at left and ending at right in the
;current buffer a localizable string, assuming that the
;string is within php context
(defun make-localizable-string-in-php-context(left right)
(goto-char left)
(insert "_(")
(goto-char (+ right 2))
(insert ")")
)

;makes the text starting at left and ending at right in the
;current buffer a localizable string, assuming that the
;string is within html context
(defun make-localizable-string-in-html-context(left right)
(goto-char left)
(insert "<?= _('")
(goto-char (+ right 7))
(insert "'
)?>")
)

;makes the highlighted text a localizable string
;uses php-context localization if the first char highlighted
;is " or '
;otherwise uses html-context localization
(defun make-localizable-string()
(interactive)

;find the positions of the left and right ends of
;the highlighted text
(if (> (point) (mark))
(progn
(setq right (point))
(setq left (mark))
)
(progn
(setq right (mark))
(setq left (point))
)
)

;determine php-context or html-context and dispatch
(if (or (char-equal (char-after left) ?\") (char-equal (char-after left) ?'))
(make-localizable-string-in-php-context left right)
(make-localizable-string-in-html-context left right)
)
(deactivate-mark)
)

;to handle php strings which contain html tabs
;we dont want to translate the html tabs
(defun make-localizable-string-within-php-string ()
(interactive)

;find the positions of the left and right ends of
;the highlighted text
(if (> (point) (mark))
(progn
(setq right (point))
(setq left (mark))
)
(progn
(setq right (mark))
(setq left (point))
)
)
(goto-char left)
(insert "\". _(\"")
(goto-char (+ right 6))
(insert "\").\"")
(deactivate-mark)
)

;assigns a keyboard shortcut
(global-set-key "\C-l" 'make-localizable-string)
(global-set-key "\C-k" 'make-localizable-string-within-php-string)
suchy(d)ivan(a)gmail.com
10.12.2005 13:35
Default behavior is name .mo file equally in every language version:
===
locale_dir

--- en_US
------ LC_MESSAGES
--------- lang.mo

--- sk_SK
------ LC_MESSAGES
--------- lang.mo
===

I think, better form is:
===
locale_dir

--- en_US
------ LC_MESSAGES
--------- en.mo

--- sk_SK
------ LC_MESSAGES
--------- sk.mo
===

Then the following code works very well (surprisingly on win32 too), and you don't need restart apache and do other confusing things:

<?php
$gettext_domain
= 'sk'; // change by language
setlocale(LC_ALL, 'sk_SK.UTF-8'); // change by language, directory name sk_SK, not sk_SK.UTF-8
bindtextdomain($gettext_domain, "lang");
textdomain($gettext_domain);
bind_textdomain_codeset($gettext_domain, 'UTF-8');
?>

Have nice day :-)
smerf(a)druid(d)if(d)uj(d)edu(d)pl
31.10.2005 10:38
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)
florent at eledo dot com
30.08.2005 16:05
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
20.05.2003 16:23
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.
hardy at acm dot org
18.03.2003 18:12
After many hours of tests/debug I found this behaviour in Red Hat 7.3 (I don't  test with other versions/distros)

The i18n settings doesn't work if not exits the right country code under  
/usr/lib/locale/. On my original instalation I just haved /usr/lib/locale/en* files, so after reinstall the glibc-common package the example showed here it works !.

* To force reinstall of the package

     rpm -i --force glibc-common-2.2.5-34.i386.rpm

* The working example $HOME/i18n.php

----begin----
#!/usr/bin/php
<?php
// Current locale settings
echo "Current i18n:".setlocale(LC_ALL, 0)."\n\n";

// i18n support information here
$language = 'es_ES';
$newLocale=setlocale (LC_ALL, $language);
echo
"After i18n:$newLocale\n\n";

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

echo
gettext("The string must be here\n");
?>
----end----

* My $HOME/locale/es_ES/LC_MESSAGES/messages.po

----begin----
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2003-03-18 10:52+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"

#: i18n.php:16
msgid "The string must be here\n"
msgstr "La cadena debe ir aquí\n"
----end----

I hope this helps to you

Thanks
Hardy Beltran Monasterios
jespersaNOSPAM at diku dot NO_SPAM dot dk
5.05.2002 14:27
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.
iguy at ionsphere dot org
5.03.2001 5:18
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".



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)