PHP Conference Japan 2024

Gettext 函數

目錄

新增註解

使用者貢獻的註解 37 個註解

11
jeremy at jeremy dot se dot nospam
17 年前
如你們有些人提到的,您必須先在您的系統上編譯語言環境。如何完成此操作取決於您的系統/發行版 *嘆氣*

在任何情況下,您都需要在您的系統上安裝 gettext。執行最新版本 libc 的 Linux 使用者已經在 libc 中安裝了 gettext。

以下是給執行 Ubuntu Edgy 的使用者的範例。

首先,請查看 /usr/share/i18n/SUPPORTED,這裡列出您的系統支援的語言環境。要編譯語言環境,我們將使用命令「locale-gen」。(「man 8 locale-gen」是很好的閱讀材料)

此命令從 /var/lib/locales/supported.d/ 資料夾中的檔案讀取設定。在這些檔案中定義了語言環境和字元集。

如果我們以瑞典語為例,請先在 /var/lib/locales/supported.d/ 中建立一個名為「sv」的檔案,然後放入類似「sv_SE.UTF8 UTF8」(不含「」)的內容。這表示我們希望使用字元映射 UTF-8 來建置語言環境 sv_SE。請檢查 /usr/share/i18n/SUPPORTED 檔案以取得其他替代方案。

現在我們執行「locale-gen」,這會編譯 /var/lib/locales/supported.d/ 中定義的所有語言環境,並將它們放入 /usr/lib/locales 中(是的,有很多位置...)

現在您已經準備就緒...

建立一個 php 檔案(例如 hello.php),其中您要翻譯的所有字串都用 _("string here"); 包圍。

接下來執行「xgettext hello.php」,這會建立一個名為 messages.po 的檔案,這是您的翻譯檔案 (pot)。在此檔案中變更「Content-Type: text/plain; charset=CHARSET\n」,並在此情況下將 CHARSET 替換為 UTF-8。接下來翻譯所有像這樣的字串。

#: hello.php:3
msgid "hello!"
msgstr "hej!"

儲存並使用命令「msgfmt -o hello.mo messages.po」,這會建立一個名為 hello.mo 的已編譯 .mo 檔案

然後將此檔案放置在您的 Apache 可以讀取到的某個目錄結構中。結構如下所示

「locale/sv/LC_MESSAGES/hello.mo」

接下來,讓 php 知道我們正在做什麼。我們指向我們翻譯的位置。在 hello.php 的頂部新增以下內容

bindtextdomain('hello','/somepath/locale');

這會將 hello.mo 檔案繫結到您建立的 locale/ 目錄。
然後設定語言環境。LC_ALL 表示我們想要翻譯所有內容。在其他時間可能不太好,如這裡的另一個人建議。

setlocale(LC_ALL, "sv_SE.UTF-8");

最後選取我們要使用 hello.mo

textdomain('hello');

應該是這樣!試試看..

如果您遇到任何問題,請嘗試重新啟動 Apache,因為它似乎會快取語言環境。

如果您正在執行命令列,您可能也必須將環境變數 LANGUAGE 設定為您的語言環境。我不需要這樣做就可以在 apache 中運作,但您可能會需要...

putenv("LANGUAGE=sv_SE.UTF-8");
8
C Snover
18 年前
我認為值得一提的是,您會發現的大多數文件和教學課程都說您應該 setenv(LC_ALL, $locale),但這只有在語言環境在本地機器上有效時才有效。如果您使用的語言環境在系統上不存在或無效(例如從 HTTP Accept-Language 標頭傳回的內容,例如「ja」,這永遠不是有效的語言環境,因為它不包含國家/地區代碼 JP),您可能會為了找出該死的事情為什麼不起作用而焦頭爛額。

我發現設定 LANGUAGE 變數(例如 setenv("LANGUAGE=$locale"))將允許 gettext 在您的語言環境目錄中搜尋,即使語言環境實際上在本地系統上無效也一樣。

因此,總結來說

這將會有效
<?php
$locale
= 'ja'; // 假設這是從 Accept-Language 標頭傳來的
$locale_dir = './locale'; // 您的 .po 和 .mo 檔案應位於 $locale_dir/$locale/LC_MESSAGES/messages.{po,mo}

putenv("LANGUAGE=$locale");
bindtextdomain('messages', $locale_dir);
textdomain('messages');
?>

這將不會有效
<?php
$locale
= 'ja';
$locale_dir = './locale';

putenv("LC_ALL=$locale");
bindtextdomain('messages', $locale_dir);
textdomain('messages');
?>

這也不會有效
<?php
$locale
= 'ja';
$locale_dir = './locale';

setlocale(LC_ALL, $locale);
bindtextdomain('messages', $locale_dir);
textdomain('messages');
?>

這也不會有效
<?php
$locale
= 'ja';
$locale_dir = './locale';

setlocale(LC_MESSAGES, $locale);
bindtextdomain('messages', $locale_dir);
textdomain('messages');
?>

作為參考,此程式碼已在 Ubuntu Dapper 6.06 上的 PHP 5.1.2 + LigHTTPd 1.4.11 + gettext 0.14.5 環境中測試過。它應該也適用於任何 Linux 變體以及這些軟體的舊版本。
2
analpaper{gmail}
16 年前
回覆 richard
我使用萬用字元 * 一段時間都沒有問題,直到今天。

我使用
<?php bindtextdomain( '*', './locale' ); ?>
但它在某些環境下似乎會失敗(我不知道為什麼,但在使用相同軟體的不同機器上,結果並不總是如預期)。

然後,使用
<?php bindtextdomain( "*", './locale' ); ?>
一切又可以正確翻譯了。

我盡可能總是使用單引號,現在又多了一件事要記住。
---
live2code
2
djogopatrao at gmail dot com
18 年前
Juan Liska,我找到一個替代方案。我沒有重新命名或為語系新增別名,而是簡單地將

$language = 'pt_BR';

改成

$language = 'pt_BR.UTF-8';
putenv("LANG=$language");
setlocale(LC_ALL, $language)

它就正常運作了!
2
konrads/smelkovs/gmail/com
18 年前
關於 Windows 使用者的 LC_MESSAGES,LC_MESSAGES 應該定義為 5
2
Maxwel Leite -maxwelleite at gmail com-
19 年前
PHP-gettext 的開發目的是能夠直接讀取 gettext MO 檔案,除了 PHP 之外不需要其他任何東西
https://savannah.nongnu.org/projects/php-gettext/
2
kocio at irc dot pl
20 年前
以下三行程式碼執行約需 0.5 秒(Debian,Celeron 2GHz,256MB RAM)

setlocale(LC_ALL, 'pl_PL');
bindtextdomain('my_domain', '../dir/' . 'locale');
textdomain('my_domain');

我認為這種延遲應該在文件中提及。以我的情況來說,這表示整個腳本的執行時間增加了一倍以上。
2
dev.php at tfelber.net
21 年前
檢查您的

/etc/locales.aliases 中是否有 "english en_GB.ISO-8859-1"(之前提到過)

以及您的

/etc/locales.gen 中是否有 en_GB.ISO-8859-15 ISO-8859-15

我不確定只有這個條目是否能解決問題。在我的情況中,這個條目是由 dpkg-reconfigure locales (debian) 建立的,我在其中建立了語系。

翻譯只適用於 de_GE@euro 和 en_GB.ISO-8859-15(您 locales.gen 中的第一欄)
2
anim8
21 年前
即使在某些情況下,setlocale() 除了語言代碼之外可能還需要國家代碼,這並不表示 gettext 也需要。

如果 setlocale() 設定為 es_ES 或 es_MX,gettext() 仍會從 'es' 資料夾中的 po 檔案取得文字。

為了避免 ISO 標準的冗長,更改系統的別名檔案可能不是一個好主意,因為
a) 您可能會破壞某些東西
b) 您的程式碼失去了可攜性

.
1
richard at hirner dot at
18 年前
* 萬用字元對我不起作用(php 5)... 我必須為每個文字網域使用 bindtextdomain
1
webmaster [at] ttw [dash] tool [dot] de
18 年前
如果您想使用來自多個網域的訊息,且 .mo 檔案位於非標準位置,請記得為每個網域放置一個 bindtextdomain() 呼叫,因為「未綁定」的網域將會在標準位置(通常在 *nix 上的 "/usr/share/locale")中搜尋。

<?php

bindtextdomain
('foo','/some/dir/with/mo_files');
bindtextdomain('bar','/another/mo_file/dir');

echo
dgettext('foo','Text to be translated using the foo-catalog.');
echo
dgettext('bar','Text from a different catalog named bar.');

?>

如果您使用的所有 .mo 檔案都位於同一個目錄中,您可以使用 "*" 萬用字元,如下所示

<?php

bindtextdomain
('*','/directory/with/all/mo_files');

?>

此程式碼已在 PHP 5.1.4 上測試過
1
info at adaniels dot nl
18 年前
正如 robert at klugher dot com 所述
環境設定 'LANGUAGE' 的優先順序高於任何本機設定。這表示像幾乎所有範例那樣變更 LC_ALL/LC_MESSAGES 和 LANG 不會產生任何作用。

所以如果您已執行
<?php
$language
= "nl_NL";
putenv("LANG=$language");
setlocale(LC_ALL, $language);
...
?>
但文字仍然以英文顯示。請嘗試同時設定 LANGUAGE 變數。
<?php
$language
= "nl_NL";
putenv("LANGUAGE=$language");
putenv("LANG=$language");
setlocale(LC_ALL, $language);
...
?>
1
birkholz at web dot de
18 年前
> stefan+usenet at froehlich dot priv dot at 於 2004 年 5 月 5 日 01:30 寫道
> 一再閱讀這一行
>
> <? php setlocale(LC_ALL, 'de_DE'); ?>
>
> 我必須警告使用它,因為存在嚴重的問題。
> 對於某些語系,LC_NUMERIC 會交換句點和逗號,例如,當將資料列插入 SQL 資料庫時,可能會導致
> 小數點後面的數字被無聲無息地移除。
>所以不要這樣做,而是使用
>
> <? php setlocale(LC_MESSAGES, 'de_DE'); ?>
>
> 來代替,它可以確切地執行您想要的操作,而不會有任何不良的副作用。

對於所有 Windows 使用者
請注意,LC_MESSAGES 在 Windows 上似乎沒有透過 PHP 5.1.2 設定,因此如果您為 Linux 系統開發應用程式,並想使用 gettext 使其成為多語言,您在 Windows 開發環境中使用 LC_MESSAGES 時會遇到問題。
您可以嘗試透過在您的腳本中加入以下程式碼來解決此問題

<?php if (!defined('LC_MESSAGES')) define('LC_MESSAGES', 6); ?>

如果您將 LC_MESSAGES 傳遞給 setlocale() 函式,就不會收到警告。
1
Juan Liska
19 年前
如果您在 ubuntu 或 debian 上使用 setlocale 時遇到問題(如果它傳回 false)

nano /etc/locale.gen

請確保您要使用的語系在清單中,如果沒有,請新增它們。例如,我想要 es_GT (因為我有一個必須在 redhat 和 debian 上執行的應用程式,我無法變更為 es_GT.UTF-8) 所以,新增

es_GT UTF-8

然後執行

locale-gen

您現在擁有您想要的語系,而不僅僅是系統神奇地提供的語系
1
milky#users:sf/net
19 年前
有一個 gettext 函式的模擬版本 - 明顯比原生綁定慢,但可以在缺乏擴充功能的共用伺服器上使用。它被認為是相當有用的後備方案(已封裝在 if-function_exists 檢查中)。
請參閱 [ http://freshmeat.net/p/upgradephp ] tarball 中的 ext/ 目錄。那裡不支援複數翻譯,因為這太難以可靠地重新實作。
1
zixia at zixia dot net
20 年前
如果 gettext 無法使用您的語系,例如 'zh_CN',請查看 "localedef --list-archive" 命令的輸出是否包含您的語系(在此範例中為 'zh_CN')。
如果沒有,請嘗試使用現有的語系或使用 "localedef" 建立一個:在我的情況下是 "localedef -f GBK -i zh_CN zh_CN"。
1
wouter at grep dot be
21 年前
當然,只有在您為使用者提供他要求的語言和編碼時,翻譯才有趣。由於 HTTP 通訊協定的一部分允許您指定這一點,如果能夠使用該資訊從您提供的列表中挑選出「正確」的翻譯,那就太好了。

我寫了一些可以做到這一點的東西 - 它會剖析 'Accept-Language' 和 'Accept-Charset' HTTP/1.1 標頭,並告訴您使用者偏好您提供的清單中的哪一個。您可以在 http://www.grep.be/articles/php-accept.php 下載。

請注意,即使使用者的瀏覽器可能支援此功能,使用者也可能不知道;因此,不移除其他語言版本的連結可能是一個好習慣,這樣人們仍然可以選擇使用他們喜歡的另一種語言版本瀏覽您的網站。
1
jc
21 年前
我在讓 gettext 運作時遇到很多問題 (RedHat 7.3)。在閱讀本手冊中的所有評論後,我讓它正常運作了。

總而言之,請注意

1) 您在 setlocale() 中使用完整的語系
2) 您的 language_country 存在於 /usr/share/locale/locale.alias 中
3) Apache 似乎需要重新啟動(我使用「graceful」就成功了)
4) 您的 .mo 檔案必須以網域命名

我的程式碼

$language = "es_ES";
$locale = setlocale(LC_ALL, $language);

$gettext_domain = 'messages';
bindtextdomain($gettext_domain, "/full/path/to/locale");
textdomain($gettext_domain);
1
Anonymous
21 年前
我讓 gettext 能夠使用標準的 "de" 或 "fr" 而非 "de_DE" 的方法是,我將我的 /usr/share/locale/locale.alias 覆寫為 /usr/lib/X11/locale/locale.alias 檔案。然後我重新啟動了 Apache。我這樣做的原因是,X11 檔案看起來更新,而且更現代化!
1
Picco
21 年前
給中文程式設計師的注意事項....

我花了幾個小時才弄清楚你不能使用

LANG=zh
而必須使用
LANG=zh_TW
在某些機器上...

一個好的測試方法是檢查 setlocale() 的回傳值
1
robert at klugher dot com
21 年前
我經過幾個小時的嘗試後發現的一個訣竅是

當你使用 setlocale() 時,PHP 會使用在例如 /usr/share/locale 中找到的 locale 資訊來設定 LC_ALL、LC_MESSAGES 等的語言資訊。

你可以透過使用 putenv() 並設定 LANG=....,然後查看 setlocale(LC_ALL, "") 的回傳值,來檢查它將使用的確切資訊。你的 gettext 函式將用來尋找翻譯檔的語言值,是 LC_MESSAGES 所給定的值。

範例

我將 LANG 設定為 fr_BE,並將翻譯檔放在 dirxxx/locale/fr_BE/LC_MESSAGES/... 中
由於我的系統中 fr_BE 有 locale 資訊,但沒有 LC_MESSAGES 的資訊,PHP 選擇使用 fr_FR 的 LC_MESSAGES 設定,然後在 dirxxx/locale/fr_FR/LC_MESSAGES/... 中尋找翻譯檔,當然找不到。

因此,請務必查看 setlocale 的回傳值,以了解哪個語言值與 LC_MESSAGES 相關聯,然後就知道 gettext 將在哪個子目錄中尋找翻譯檔。

Robert
1
php at zpod dot ca
21 年前
對於那些只是想讓腳本運作,而你的供應商不支援 gettext 的人,你可以透過新增以下程式碼來繞過國際化設定

function _($str) {
return $str;
}
1
Eneko Lacunza enlar at enlar dot net
21 年前
來自我的 Red Hat Linux 7.3 系統的一些提示。

直到我使用 setlocale 設定完整的 locale(例如 es_ES)之後,它才對我有效。

我嘗試使用 Michele Manzato 的範例(謝謝!),但由於它在設定語言時沒有包含國家/地區,所以它對我失敗了。以下是使用完整 locale 「修復」的範例

// 變更為腳本目錄
// (在 RH 7.3 中不需要)
$path = dirname(getenv(PATH_TRANSLATED));
chdir($path);

// 將語言設定為完整 locale 'es_ES'
$language = 'es_ES';
putenv("LANG=$language");
setlocale(LC_ALL, $language);

// 將文字網域設定為 'mydomain'
$domain = 'mydomain';
bindtextdomain("$domain", "./locale");
textdomain("$domain");

// 搜尋的 .mo 檔案是
// ./locale/es_ES/LC_MESSAGES/mydomain.mo
// 或者,如果前一個不存在,則是
// ./locale/es/LC_MESSAGES/mydomain.mo

echo gettext("Hello world!");

希望這有幫助!
Eneko.
1
mgvNOSPAM at fx dot ro
22 年前
如果你像我一樣一頭霧水,請注意以下事項
1. 雖然大多數註解在程式碼中列出了 setlocal(),但這實際上不是翻譯所需的 - 請閱讀「字串函式」下的文件以了解詳細資訊(此外,官方的 gettext() 範例也沒有包含它);
2. hace_x 的範例真的很酷,但你需要知道他字串結尾的所有 "n" 前面都應該有一個反斜線 - 它們實際上是 EOL 字元,但它們不知何故搞砸了,我花了兩個小時才找到原因...
0
richardbrinkman at hotmail dot com
8 年前
Gettext 會快取機器可讀的 *.mo 檔案。這使其速度非常快,但也使得在應用程式執行時無法變更 .mo 檔案。由於 PHP 是作為伺服器執行,你無法更新你的 .mo 檔案並立即看到新的翻譯。有兩種方法可以克服這個快取問題

1. 重新啟動你的 Web 伺服器。例如,使用 `systemctl restart apache2`。這將會終止正在執行的 php 處理程序,然後重新載入它們。

2. 如果你沒有權限重新啟動 Web 伺服器(例如你使用的是共用主機),你可以變更網域。例如,使用以下 PHP 程式碼將新的網域硬連結到已變更的 .mo 檔案

$locale = "nl_NL.utf8"; // 將此設定為你的語言
setlocale(LC_ALL, $locale);
putenv('LANG=' . $locale);
$mtime = 0;
$translationDir = "locale"; // 或你儲存翻譯的任何位置
$originals = glob("$translationDir/*/LC_MESSAGES/messages.mo");
foreach ($originals as $file)
$mtime = max($mtime, filemtime($file));
$domain = "messages_$mtime";
$current = glob("$translationDir/*/LC_MESSAGES/$domain.mo");
if (count($originals) != count($current)) {
foreach (glob("$translationDir/*/LC_MESSAGES/messages_*.mo") as $file)
unlink($file);
foreach ($originals as $file)
link($file, substr($file, 0, -3)."_$mtime.mo");
}
bindtextdomain($domain, $translationDir);
textdomain($domain);

此腳本所做的是檢查是否至少有一個翻譯已更新,如果是,則移除所有 messages_*.so,並將所有 messages.po 硬連結到對應的 messages_$mtime.po,其中 $mtime 設定為最近修改的翻譯檔案。由於它使用新的網域 ("messages_$mtime"),因此不會被快取。
0
Sbastien Ballest-Antich
16 年前
使用 heredoc 和帶有 sprintf 的 gettext 字串的解決方案
<?php
$hd
= <<<EOD
<p>%s</p>
<p>%s</p>
EOD;
$hdgt = sprintf($hd, _('Heredoc'), _('gettext'));
var_dump($hdgt);
?>
0
titan at phpdevshell dot org
16 年前
如果你想要建立一個 .po 檔案,其中包含大括號 {} 內的 heredoc 腳本,解決方案如下;

我想翻譯這裡的內容 (test.php)
<code>
<?php
$EOF
= <<<EOF
{
$t->__('我想翻譯這個字串。')}
EOF;
?>
</code>

你必須使用帶有 Python 解析器的 xgettext (gnu 工具),如下所示
<code>
$ xgettext --default-domain=test --keyword=__ --keyword --language=Python test.php
</code>

上面的終端機命令看起來可能錯誤,因為 --keyword 使用了兩次,但這是正確的。
0
SEWilco
17 年前
人們提出了幾種配置選項的組合。考慮嘗試使用各種語言名稱(帶有和不帶有字元集後綴)和路徑名稱的巢狀迴圈。迴圈中間的 gettext() 呼叫可以測試是否成功(字串是否被翻譯)。

「在測試的 4374 種本地化設定變化中,有 0 個成功。」

有時,你只需要修復系統和 PHP 設定。
0
jon at nospam dot foo
17 年前
我相信我會讓事情更混亂,但我還是忍不住要插一句。我曾經在這方面遇到了一些困難...

你的 gettext 安裝絕對必須支援你在 setlocale(LC_MESSAGES,$locale) 呼叫中嘗試使用的 locale。

這無效

setlocale(LC_MESSAGES,"en");

在 OpenSUSE 10.2 中,因為 /usr/lib/locale 不包含目錄 "en"(開箱即用),即使你的自訂 LC_MESSAGES 網域位置可能包含。

至少在 OpenSUSE 10.2 中,/usr/lib/locale 包含美國英語的

en_US
en_US.iso885915
en_US.utf8

(同樣,不是 "en")。

也許可以設定別名,我不確定(有人知道這方面的事情嗎)。

我的目標是使用 HTTP_ACCEPT_LANGUAGE 來設定 locale(我意識到 locale != language,但似乎 gettext 使用 locale 來分配語言(抓頭))。OS X 中的 Opera 不會傳送 "en_US"。但是,Firefox 開箱即用就會傳送。我不確定它是否應該這樣運作,但看起來應該是這樣,因此 Opera 處理這個的方式似乎有問題。順帶一提,Safari 簡單地在 HTTP_ACCEPT_LANGUAGE 中傳送 "en",這也無效。

這迫使我在我的 PHP 應用程式中設定一個可設定的預設 locale(例如 "en_US"),無論如何都應該這樣做,因為 HTTP_ACCEPT_LANGUAGE 可能會是空白。
0
tucsi at c2 dot hu
19 年前
如果你的 gettext 翻譯在安全模式下不起作用,請嘗試在 php.ini 中設定此項
safe_mode_allowed_env_vars = PHP_,LANG
0
php at dynaperl dot com
22 年前
如果你從 SuSE Dist. 安裝,你需要 glibc-locale.rpm 才能讓 gettext 運作。

mfg ralph.
0
Michele dot Manzato at verona dot miz dot it
23 年前
Gettext 很棒,但你必須考慮一些注意事項才能讓它運作。不幸的是,gettext 文件並不是那麼簡單明瞭...

使用 gettext 工具建立的 .mo 檔案必須是

[bindtextdomain 的目錄]/[語言]/LC_MESSAGES/[網域].mo

否則 gettext() 函式將無法找到它(這在 win32 中是正確的,不知道 Un*ces)。順便一提,你不會收到任何錯誤訊息,字串只會保持未翻譯的狀態。

第二,如果你在 bindtextdomain 中使用相對路徑,你必須確定目前的目錄是什麼。在某些系統上,腳本目錄可能不是目前的目錄,所以你必須使用 chdir() 切換到該目錄。

然後,當然,要檢查 PHP 的設定檔,確認已載入適當的 gettext 擴充功能。

以下是一些範例程式碼

// 切換到腳本目錄
$path = dirname(getenv(PATH_TRANSLATED));
chdir($path);

// 設定語言為 'it'
$language = 'it';
putenv("LANG=$language");
setlocale(LC_ALL, $language);

// 將文字網域設定為 'mydomain'
$domain = 'mydomain';
bindtextdomain("$domain", "./locale");
textdomain("$domain");

// 搜尋的 .mo 檔案是
// ./locale/it/LC_MESSAGES/mydomain.mo

echo gettext("Hello world!");

玩得愉快!
Michele
-1
elonen at iki dot fi
19 年前
為了製作 PHP 檔案的本地化副本 (靜態 l10n),這裡有一個 GPL 授權的命令列工具:http://iki.fi/elonen/code/pophorator/
-1
dpatton at confluence dot org
19 年前
在決定使用 gettext 之前,請務必檢查您的網頁伺服器設定,因為如果您在多執行緒環境中執行,則不應使用 gettext,因為它不是執行緒安全的。

未來版本的 gettext (可能為 0.15) 可能會是執行緒安全的。
任何 gettext 相依性,例如 glibc,也需要是執行緒安全的。

Unix 上的 Apache 1.3 通常是非執行緒的,但在 Windows 上是多執行緒的。
Apache 2.0 支援 MPM (多處理模組),其中一些支援多執行緒
https://apache-httpd.dev.org.tw/docs-2.0/mpm.html
-1
mikolaj at webgate dot bg
20 年前
winXP,PHP 4.3.5 作為 Apache1.3.29 模組

給 Windows 使用者的兩個提示。

我發現設定 locale 並非足夠或必要的。為了讓它運作,我需要將 LC_ALL 或 LANG 環境變數設定為我的 locale。無論如何,這個值必須適合 setlocale,所以最好使用它進行測試。在我的情況下,根據 http://www.unicode.org/onlinedat/countries.html,保加利亞語是 bgr_BGR。

gettext 會檢查檔案一次並將它們保存在快取中。特別是,這表示如果它找不到您的檔案,它不會再次搜尋,因此在任何目錄變更後重新啟動 Apache!

我的最小可行腳本
<?php
// 翻譯檔案:D:\Apache\htdocs\mypage\locale\bgr_BGR\LC_MESSAGES\messages.mo
putenv("LC_ALL=bgr_BGR");
bindtextdomain('messages', 'D:\Apache\htdocs\mypage\locale\\');
echo
gettext("Hello");
?>
-1
stefan+usenet at froehlich dot priv dot at
20 年前
讀取這行

<? php setlocale(LC_ALL, 'de_DE'); ?>

這裡反覆出現,我必須警告使用它,因為存在嚴重的隱患。對於某些 locale,LC_NUMERIC 會交換句點和逗號,這可能會導致例如將資料列插入 SQL 資料庫時,小數點後的數字被靜默地移除。所以不要這樣做,而是使用

<? php setlocale(LC_MESSAGES, 'de_DE'); ?>

相反,它會精確地完成您想要的操作,而不會產生任何令人討厭的副作用。
-1
Anonymous
23 年前
對你們許多人來說可能很明顯,但我認為值得一提的是,網域是包含字串目錄的 .mo 檔案的名稱 (不含副檔名)。

因此,如果您在 './locale/lg/LC_MESSAGE' 中為每個頁面都有一個 myPage.mo 目錄,並且在 '/global/locale/lg/LC_MESSAGE' 中有一些通用目錄 (例如 errorMsg.mo),則您可以執行

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

Ivan
To Top