百科狗-知识改变命运!
--

gettext() - gettext库(多语言支持)

梵高12个月前 (11-21)阅读数 48#技术干货
文章标签注释

gettext()

(PHP 4, PHP 5, PHP 7)

Lookup a message in the current domain

说明

gettext(string $message): string

Looks up a message in the current domain.

参数

$message

gettext() - gettext库(多语言支持)

The message being translated.

返回值

Returns a translated string if one is found in the translation table, or the submitted message if not found.

范例

gettext()-check

注释

Note:

You may use the underscore character '_' as an alias to this function.Note:

Setting a language isn't enough for some systems and the putenv() should be used to define the current locale.

参见

  • setlocale()设置地区信息
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.
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):

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)
As of php 5.3, you can use the following code to get the preferred locale of the http agent. 
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.
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()

Now the cache is forced to flush every time.
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', ''); //ie: C:/wamp/www/your_app/locale
$locale = ''; //ie: es_CO
$domain = 'your_gettext_domain'; //ie: messages
putenv('LC_ALL=' . $locale);
bindtextdomain($domain, LOCALE_DIR);
textdomain($domain);
echo _(''; // 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.
Depending on the implementation of gettext used you might have to call the setlocale(LC_ALL, "") command. 
So your example code would be 

NOTE: If setlocale returns NULL the LANG specified is invalid and "not supported".
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.
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:

I had a lot of trouble getting this to work on Red Hat (Yellow Dog) Linux though.
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:

The following will NOT work: 
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: 
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.
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.
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.
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  
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 "

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)