SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

PEARライブラリ活用

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

PEARライブラリ活用 (8)

  • X ポスト
  • このエントリーをはてなブックマークに追加

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>

次のページ
File_Gettext

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
PEARライブラリ活用連載記事一覧

もっと読む

この記事の著者

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

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

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

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3040 2008/10/14 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング