unoh.github.com

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

2006-06-28 15:49:16 +0000

ジュンヤです。

5分でわかる PHP で書かれた Web サービスの国際化(その2)に続き、今回はメッセージの切替えの例を紹介したいと思います。これらはフォト蔵とその英語版PhotoZou.comで実際におこなっている例です。(厳密に言うとフォト蔵では、gettext ではなく独自の仕組みを使っていますが、基本的な考え方は全く同じなので、以下同じ事例を gettext に引きなおして説明しています。)

まずはメッセージの内容の一部を変数にして自由に入れ変えたいという場合。

エラーメッセージで「○○は△△文字以上です。」と表示したいとき、

msgid "%1$s has exceeded the limited capacity of %2$s characters."
msgstr "%1$sが%2$s文字以上です。"
msgid "Your Comment"
msgstr "コメント"


という日本語のメッセージファイルを用意し、実際に表示するときは、プログラムで

$message =  gettext('%1$s has exceeded the limited capacity of %2$s characters.');
$item = gettext('Your Comment')
printf($message, $item, 200);


というように printf を使います。printf の第1引数 $item が言語が日本語なら「コメント」になり、$format の %1$s に入るわけです。第2引数の200は %2$s に代入されるので、結果として日本語では、「コメントが200文字以上です。」と表示されます。

gettext では msgid に対応するその言語の msgstr が呼びだされますが、もし対応するメッセージファイルがない場合、あるいは msgstr が定義されていないときには、msgid がそのまま表示されます。ですから、msgid は万一表示されてしまっても構わないように、きちんと意味の通じる英語にしておくべきです。たとえば、

Add favorite msg1


といった無意味な msgid は避けるべきでしょう。

次に、良く問題となる名前の表示部分。姓と名がどちらが先かという順番は国ごとに異なるので、表示部分をメッセージファイルで以下のように定義します。

#
# 英語メッセージファイル
#
msgid "%1$s %2$s"
msgstr "%1$s %2$s"


#
# 日本語メッセージファイル
#
msgid "%1$s %2$s"
msgstr "%2$s %1$s"


プログラム中では

$name = gettext('%1$s %2$s')
printf($name, $first_name, $last_name);


のように呼びだします。

$first_name、$last_name にそれぞれ代入される名前と苗字は英語ではそのまま表示され、日本語では反転します。

ただ、この仕様は、真に国際化されたアプリケーション向きではありません。
国・言語によっては、そもそも名前と苗字という概念がないところもあるので、名前全体をひとくくりで扱うほうがよいのかもしれません。

その場合は、名前の入力を促すフォームでは一つのテキストフィールドで扱い、データベースに保存するときも name というフィールドを一つだけ用意します。上記で説明したように順番を入れ替える必要もなくなり、シンプルな作りとなります。