18

数か月前に gettext を使用していくつかのテストを実行したことを覚えていますが、次のコードは完全に機能しました。

putenv('LANG=l33t');
putenv('LANGUAGE=l33t');
putenv('LC_MESSAGES=l33t');

if (defined('LC_MESSAGES')) // available if PHP was compiled with libintl
{
    setlocale(LC_MESSAGES, 'l33t');
}

else
{
    setlocale(LC_ALL, 'l33t');
}

bindtextdomain('default', './locale'); // ./locale/l33t/LC_MESSAGES/default.mo
bind_textdomain_codeset('default', 'UTF-8');
textdomain('default');

echo _('Hello World!'); // h3110 w0r1d!

これは完全に機能しました (私の記憶が正しければ Windows XP と CentOS で)。これは、システムにインストールされているかどうかを気にすることなく、任意の「ロケール」を使用できるので良かったです。しかし、これはもう機能していないようです。なぜだろうか...


レッドハット + PHP 5.2.11:

さまざまなロケールから前後に切り替えることができ、setlocale()呼び出しが false を返さない限り (ロケールが利用可能/システムにインストールされている場合)、翻訳は正しく表示されます。

これは完璧ではありません (ロケールの存在をテストせずに、gettext を任意の翻訳ディレクトリに向けることができれば素晴らしいことです) が、許容範囲内です。後でさらにいくつかのテストを実行します。

Windows 7 + PHP 5.3.1 (XAMPP):

setlocale()、またはなどの有効な Windows ロケールを使用しない限り、 (LC_ALLの代わりに使用している場合でも)常に false を返します。この場合、ロケールは正しく設定されているようですが、翻訳はまだ表示されません。何百ものタブを開いているので、今はテストできませんが、そのスクリプトへの最初の呼び出しで正しい翻訳が得られると思います (Apache を再起動してもうまくいきません)。LC_MESSAGESengdeuptg

これがPHP Bug #49349に関連しているかどうかはわかりません。これを数時間テストします。


gettext 拡張機能 ( php-gettextZend Translate Adapterのような純粋な PHP 実装ではない) を異なるオペレーティング システム間で (おそらくのようなカスタムロケールで) 確実に使用する方法はありますl33tか?

また、必ず使用する必要がありますsetlocale(LC_ALL, ...)か?TIMENUMERICおよびMONETARY(特に)ロケール設定はそのままにしておくことをお勧めします(POSIXロケールをデフォルトに設定します)。


setlocale()アイデアがありました...非常に一般的なロケール ( CPOSIXまたは など) で呼び出しen_US、ドメインを介して言語を指定することは可能でしょうか? このようなもの:

/lang/C/LC_MESSAGES/domain.pt.mo
/lang/C/LC_MESSAGES/domain.de.mo
/lang/C/LC_MESSAGES/domain.en.mo
/lang/C/LC_MESSAGES/domain2.pt.mo
/lang/C/LC_MESSAGES/domain2.de.mo
/lang/C/LC_MESSAGES/domain2.en.mo

これは *nix および Windows プラットフォームで問題なく動作しますか?

4

2 に答える 2

19

Gettextは、Webアプリケーションにとってあまり実用的ではありません。

  • たとえば、Accept-Languageスタイルの設定をそれ自体で尊重/使用することはありません。
  • 通常、共有Webホスト(mod_php SAPI)でキャッシュの問題が発生します。

そのため、PHPモジュールが存在しないことを望む場合があり、便利_()な関数名のショートカットをユーザーランドの実装で利用できるようになりました。
(私自身のgettext.phpを持っていましたが、これはより信頼性が高く機能しました。)

あなたのオプション:

  1. とにかく、いくつかのバグレポートによると、gettextのWindowsポートにはUTF-8にいくつかの欠陥がありました。たぶんあなたのバージョンは再び影響を受けます。だからbind_textdomain_codeset('default', 'ISO-8859-1');、初心者のために試してみてください。また、Windows IIRCの環境変数を好むようであるため、putenv("LC_ALL", "fr_FR");よりもうまく機能する可能性がありsetlocale()ます。後でdl(gettext.dll)を実行すると、特に機能します。

    また、そこに文字セットを含めるチャンスを与えてLANG=en_GB.ISO-8859-1ください。(とにかくソーステキストは英語なので、ここでは文字セットを気にすることはあまり重要ではありませんが、gettextがそれ自体をつまずく一般的なケースです。)ああ、時にはUTF-8ではなくUTF8です。ASCIIも試してください。

  2. または、gettextを回避します。あなたのドメインのアイデアは近いですが、言語には事前定義された./locale/サブディレクトリを使用します。

    ./lang/en/locale/C/LC_MESSAGES/domain.mo
    

    bindtextdomain("default", "./lang/{$APP_LANG}/locale")次に、gettextに多くの解釈の余地を与えずに呼び出すだけです。常に/C/を検索しますが、正しいロケールディレクトリがすでに挿入されています。ただし、とにかく$LANGから/C/へのシンボリックリンクを含めるようにしてください。

  3. ヌーをかみます。gettextをあきらめます。「PhpWiki」には、カスタムのawk変換スクリプトがありました。.poファイルを.php配列スクリプト(ええ、非常に古い学校)に変換し、代わりに__()関数を使用します。選ぶ。そして、より信頼性があります。

于 2010-08-21T01:24:43.407 に答える
6

このコードは、すべてのシステムで完全に実行されるわけではありません。これは、すべてのシステム ロケール リポジトリと PHP のバージョンが異なるなどの理由からです。

一貫性が必要な場合は、Zend_Translate のようなものを使用する必要があります。Zend を各システム (同じバージョン) にインストールすると、同じローカリゼーション データ、ロケール名、およびコードベースを使用しているため、相互に一貫性が保たれます。

には多数のバグがありsetlocale、信頼性が低いだけです。@ http://php.net/manual/en/function.setlocale.phpのコメントを参照してください。

于 2010-08-17T15:14:10.780 に答える