unoh.github.com

5分でわかる PHP で書かれた Web サービスの国際化(その2)

Tue Jun 20 04:26:52 -0700 2006

ジュンヤです。

5分でわかる PHP で書かれた Web サービスの国際化 に続いて gettext の話。

以下、英語で「Hello」、日本語で「こんにちは」と表示する簡単なプログラム hello.php です。

<?php
$language = 'en';
if (ereg('ja', $_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
    $language = 'ja_JP';
}
// Set locale and default domain.
putenv("LANG=$language");
setlocale(LC_ALL, $language);
$domain = 'messages';
bindtextdomain($domain, "/var/www/html/locale");
textdomain($domain);
// Output
echo gettext("Hello");
?>


日本人がこのページを見たときは日本語で、それ以外は英語で表示するには、以下のように環境変数 HTTP_ACCEPT_LANGUAGE を見て日本語(ja)があれば $language に ja_JP をセットします。

$language = 'en';
if (ereg('ja', $_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
    $language = 'ja_JP';
}


HTTP_ACCEPT_LANGUAGE には、たとえばIEであれば、[ツール] > [インターネットオプション] の [言語] で選択されている言語すべてが ja,en のようにカンマ区切りで列挙されます。日本語版のIEを使っていれば、デフォルトの設定で必ず日本語が選択されているので、その場合には日本語を表示するようにしているわけです。

putenv("LANG=$language");
setlocale(LC_ALL, $language);


で環境変数 LANG を ja_JP に、そして ja_JP の影響を受ける範囲を LC_ALL(文字列、数値、日時などすべて)に設定します。

$domain = 'messages';
bindtextdomain($domain, "/var/www/html/locale");
textdomain($domain);


bindtextdomain では、以降作成するメッセージファイルの場所を指定し、textdomain でデフォルトで使用するメッセージファイルの名前を messages に指定しています。

echo gettext("Hello");


最後に Hello をキーとして言語に応じたメッセージを出力しています。

さて、プログラムはこれだけですが、それぞれの言語に対応したメッセージを管理するファイルをあらかじめ作成しておく必要があります。

bindtextdomain で指定した場所以下に次のような構成でディレクトリをつくります。

locale
    /en
        /LC_MESSAGES
    /ja_JP
        /LC_MESSAGES


次にコマンドラインから

xgettext -n hello.php


と実行することによりプログラム中で gettext が使われている部分、すなわち言語によって切り替える部分を messages.po というファイルに吐き出します。

messages.po は

# FIRST AUTHOR , YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-06-20 17:44+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: gettext.php:13
msgid "Hello"
msgstr ""


といった内容になっています。

これを各言語用に LC_MESSAGES の下にコピーして、msgstr の中に各言語のメッセージを入力します。つまり、ja_JP の下の messages.po は

#: gettext.php:12
msgid "Hello"
msgstr "こんにちは"


en 以下の messages.po は

#: gettext.php:12
msgid "Hello"
msgstr "Hello"


にします。

それと、

"Content-Type: text/plain; charset=CHARSET\n"


の部分は

"Content-Type: text/plain; charset=utf-8\n"


と文字コードを指定しておかないと、次に実行する msgfmt でエラーが表示されます。messages.po はここで指定した文字コードで保存しておく必要があるので注意してください。

これだけでは gettext はうまくメッセージを読み込んでくれなくて、うまく読み込むようにするには、それぞれの messages.po に対してコマンドライン上で、

msgfmt messages.po


と実行します。すると gettext が理解できる形になった messages.mo というファイルができあがります。

最終的には、以下のようにファイルが配置された形になります。

locale
    /en
        /LC_MESSAGES
             messages.po
             messages.mo
    /ja_JP
        /LC_MESSAGES
             messages.po
             messages.mo


これで hello.php にアクセスするとめでたくブラウザの言語設定に応じて表示される内容が切り替わります。

以上が gettext の基本的な仕組みです。なお フォト蔵とその英語版 PhotoZou.com では独自の仕組みでメッセージを切り替えているのですが、その仕組みはほとんどこの gettext と同じです。

次回以降はもう少し複雑なメッセージの切り替え方法や実際にフォト蔵を英語化したときの事例などを紹介していきたいと思います。

参考: