CodeZine(コードジン)

特集ページ一覧

Gettextによるウェブアプリケーションの国際化と地域化

PEARライブラリ活用 (8)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/10/14 14:00
目次

PHP標準のGettext

 PHPで標準サポートされているGettextを試します。

ソースコードにメッセージIDを埋め込む

 メッセージ文字列はソースコードには記述しません。ソースコードには、メッセージ文字列の代わりにメッセージIDを埋め込みます。埋め込みにはgettext関数を使います(gettextではなく単に_と書くこともできます)。最終的に出力したいメッセージ文字列が「タイトル」だったとしても、ソースコードには'タイトル'ではなく_('title')のように書くのです('title'がメッセージIDです)。

 ここではcharsettitlehi %s %s.という3つのメッセージIDを導入します(charsetはUTF-8に統一すべきなのですが、Windows版のPHPでは、Japanese_Japan.UTF-8が使えないため、charsetを操作できるようにしました。これはあまりよい方法ではありません)。

trans.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo _('charset') ?>" />
<title><?php echo _('title') ?></title>
</head>
<body>
<p><?php
$firstName='Taro';
$lastName='YABUKI';
printf(_('hi %s %s.'),$firstName,$lastName);
?></p>
</body>
</html>

テンプレート

 _関数(あるいはgettext関数)を含んだソースコードから、xgettextコマンドを使ってメッセージIDを抜き出します(--from-codeで.phpファイルの文字コードを、-oで出力ファイルを指定しています)。

xgettext trans.php --from-code=utf-8 -o messages.pot

 次のようなファイルmessages.potが生成されます。このファイルが、翻訳のためのテンプレートになります。

(略)
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: trans.php:16
msgid "charset"
msgstr ""

#: trans.php:17
msgid "title"
msgstr ""

#: trans.php:23
#, php-format
msgid "hi %s %s"
msgstr ""

POファイル(メッセージカタログ)

 ロケールごとにメッセージカタログを置くためのディレクトリを作り、テンプレートをコピーします。

mkdir -p locale/Japanese_Japan/LC_MESSAGES
mkdir -p locale/English/LC_MESSAGES

cp messages.pot locale/Japanese_Japan/LC_MESSAGES/messages.po
cp messages.pot locale/English/LC_MESSAGES/messages.po

 各poファイルを翻訳します。charsetの部分も書き換えて、そこで指定した文字コードで保存してください。たとえば、日本語の場合は次のようになります(保存する文字コードの選択肢にWindows-31Jがないときは、Shift_JISでいいでしょう)。

locale/Japanese_Japan/LC_MESSAGES/messages.po
(略)
"Content-Type: text/plain; charset=Windows-31J\n"
"Content-Transfer-Encoding: 8bit\n"

#: trans.php:16
msgid "charset"
msgstr "Windows-31J"

#: trans.php:17
msgid "title"
msgstr "タイトル"

#: trans.php:23
#, php-format
msgid "hi %s %s."
msgstr "こんにちは、%2$s %1$s。"

 英語の場合は次のようになります。

locale/English/LC_MESSAGES/messages.po
(略)
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"

#: trans.php:16
msgid "charset"
msgstr "ISO-8859-1"

#: trans.php:17
msgid "title"
msgstr "Title"

#: trans.php:23
#, php-format
msgid "hi %s %s."
msgstr "Hello %s %s."

 "hi %s %s."の部分の違いに注目してください。英語の場合はメッセージIDと同じ順番(つまりfirstName、lastNameの順)なのでそのままでいいのですが、日本語の場合はlastName、firstNameの順にしなければならないので、数値$という記法を使って順番を変えています。

MOファイル(バイナリファイル)

 msgfmtコマンドでPOファイルからMOファイルを作ります。メッセージ文字列はMOファイルから読み出されます。

pushd locale/Japanese_Japan/LC_MESSAGES
msgfmt messages.po
popd

pushd locale/English/LC_MESSAGES
msgfmt messages.po
popd

MOファイルの利用

 上で作成したMOファイルを利用するためには、少し準備が必要です。

 まず、ロケールを設定します。ブラウザで最優先に設定されている言語が英語ならEnglishに、そうでなければJapanese_Japan.932に設定します(Japanese_Japan.UTF-8は使えません)。これはWindowsの場合です。Windows以外ではja_JP.UTF-8などの形式を利用できるでしょう(これはよい設定方法ではありません。後述のI18Nv2を利用する方法の方がよいでしょう)。

trans.php
$tmp=mb_substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],0,2);
if ($tmp=='en') $language = 'English';
else $language='Japanese_Japan.932';
putenv("LANG=$language");
setlocale(LC_ALL, $language);

 次に、利用するドメインを指定します。ドメインとはメッセージ文字列の管理単位のことで、ドメインとロケール、メッセージIDを指定することによって、メッセージ文字列が確定します。ドメイン名とMOファイルのファイル名は揃っていなければなりません。

trans.php
$domain='messages';
bindtextdomain($domain, './locale');//ドメインとディレクトリの対応付け
textdomain($domain);//ドメインを指定

 以上をまとめると、PHPファイルは次のようになります。ブラウザの言語設定において、英語を最優先にすると英語のメッセージが、日本語を最優先にするとを日本語メッセージが表示されます。

trans.php
<?php
//言語とロケールの簡易設定
$tmp=mb_substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],0,2);
if ($tmp=='en') $language = 'English';
else $language='Japanese_Japan.932';//Japanese_Japan.UTF-8は使えない
putenv("LANG=$language");
setlocale(LC_ALL, $language);
//gettextの設定
$domain='messages';
bindtextdomain($domain, './locale');
textdomain($domain);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo _('charset') ?>" />
<title><?php echo _('title') ?></title>
</head>
<body>
<p><?php
$firstName='Taro';
$lastName='YABUKI';
printf(_('hi %s %s.'),$firstName,$lastName);
?></p>
</body>
</html>

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:PEARライブラリ活用

もっと読む

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 矢吹 太朗(ヤブキ タロウ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5