2017年4月
« 3月    
 12
3456789
10111213141516
17181920212223
24252627282930

カテゴリー

最近のコメント

<!–:ja–>PHP国際化プログラミング – gettextを使った国際化<!–:–><!–:en–>PHP Internationalization Programming – Internationalization By gettext<!–:–>

ソフトウェア国際化ツールWorld Wide Navi(ワールドワイドナビ)の国際化プログラミング参考情報から、PHPの国際化の抜粋その2です。

1. ローカライズする文字列をgettext関数に配置
ローカライズしたい文字列をgettext関数(殆どの場合、”_()”)内に配置します。
これらの文字列は、各外部リソースファイルによってローカライズ(翻訳)されます。

echo "Hello from PHP!";
-> echo _("Hello from PHP!");

2. 初期化コードを記述
ユーザーロケール(言語と地域)を適用し、リソースの名前とパスをgettextの仕組みに教えます。

index.php (または他のphp)

<?php require_once(
$_SERVER["DOCUMENT_ROOT"]."/
gettext/wwnaviRs/" .
"wwnavi.gettext.php");?>
// ロケールの設定およびgettextの
読み込みのための初期化コードの実行
...
echo _("Hello from PHP!");
...
wwnavi.gettext.php // 初期化コード

require_once("wwnaviLang.php");
// 後に使う、
// 言語と地域の配列

$header = $_SERVER[
"HTTP_ACCEPT_LANGUAGE"];
// 言語情報を持った、
ユーザーのHTTPヘッダーの取得

$lang="";
// HTTPヘッダーからロケールを解析
// ロケールの表現は、各Webブラウザによって異なりますが
// ("en"、"en-us"、"en_US"...)、
// setlocaleの引数は、
// "language_REGION"である必要があります。
if(strpos($header, ",")>0) {
 $hds = explode(",", $header);
 $lang = $hds[];
 $lang = str_replace("-", "_",
 $lang);
 if(strpos($lang, "_")>0) {
 $ls = explode("_", $lang);
 if(count($ls)>1) $lang =
 $ls[] . "_" . strtoupper($ls[]);
 }else if(!empty($wwnaviLang[$lang]
 )) {
 $lang .= "_" . $wwnaviLang[
 $lang];
 // 言語コード(例: "en")
 // のみの場合、地域コード(例: "US")を、
 // 予め定義された配列から追加します。
 // setlocaleは、完全なロケール名を必要と
 // するからです。
 }
}
//echo $lang . "
";
//putenv("LC_ALL=$lang");

setlocale(LC_ALL, $lang);
// $langは少なくとも、
// 言語と地域(例:"en_US")である必要があります。

$domain = "wwnaviBundle";
// gettextのリソース名と
// パスを教えます。
bindtextdomain($domain,
dirname(__FILE__));
textdomain($domain);
bind_textdomain_codeset(
$domain, "UTF-8");
wwnaviLang.php // 予め定義された、
// 言語とデフォルトの地域のコードの配列

$wwnaviLang = array(
...
"de"=>"DE",
"en"=>"US",
"es"=>"ES",
"et"=>"EE",
"eu"=>"ES",
"fa"=>"IR",
"fi"=>"FI",
"fo"=>"FO",
"fr"=>"FR",
...
"ja"=>"JP",
...

3. gettextのマスターテンプレートリソース(.POT)の作成
msgidとmsgstrのペアを持つ、マスターリソース(.pot)を、リソースパスの下に作成する必要があります。
xgettextコマンドは、”_()”文字列をスキャンし、potファイルを作成するのに便利です。

YOUR_DOCUMENT_ROOT/gettext/
wwnaviRs/(*1)
 ... wwnaviBundle.pot(*1)

*1)上記コードで
指定されたものと同じディレクトリ
wwnaviBundle.pot
...

#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-03-05 17:32 0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: /...../examples/php/gettext/index.php:10
msgid "Hello from PHP!"
msgstr ""

#: /...../examples/php/gettext/index.php:13
msgid "This is a DIV text."
msgstr ""
...

#: /root/wwnavi/workspace/examples/php/
gettext/sub/sub2/sub2.php:31
#, php-format
msgid "My local time is %c!"
msgstr ""
xgettext -j -L php -k"_" --from-code=UTF-8 -o
/..../examples/php/gettext/wwnaviRs/
wwnaviBundle.pot \
 /..../examples/php/gettext/index.php

4. .POTを各言語リソース(.PO)にローカライズ
マスターテンプレートを、対象ロケールのディレクトリ(LOCALE(例:”ja_JP”)/LC_MESSAGES)に、.poファイルとしてコピーし、msgstrを翻訳します。

日本語への翻訳の場合

YOUR_DOCUMENT_ROOT/gettext/
wwnaviRs/ja_JP/LC_MESSAGES
 ... wwnaviBundle.po
ja_JP/LC_MESSAGES/wwnaviBundle.po
...

#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-03-05 17:32 0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: /...../examples/php/gettext/index.php:10
msgid "Hello from PHP!"
msgstr "PHPからこんにちは!"

#: /...../examples/php/gettext/index.php:13
msgid "This is a DIV text."
msgstr "これはDIVのテキストです。"
...

#: /root/wwnavi/workspace/examples/php/gettext/
sub/sub2/sub2.php:31
#, php-format
msgid "My local time is %c!"
msgstr "わたしの現地時間は%cです!"

***注意: “%c”のようなフォーマット文字を修正(翻訳)してはいけません。


5. .POを.MO(リソースバイナリ)にコンパイル

msgfmtコマンドを実行し、リソースバイナリ(.mo)を対象ロケールディレクトリに作成します。

msgfmt -o wwnaviBundle.mo wwnaviBundle.po

これで、ブラウザの言語設定を変更しながら、英語と日本語のメッセージを切り替えられるようになります。

これらの処理は、World Wide Navi内のPHPの文字列外部化のサンプルで確認できます。

POT/POのローカリゼーションのプロセスは、ローカリゼーションツールSisulizerを使うことで、より簡単に効果的になります。



&amp;amp;lt;!–:ja–&amp;amp;gt;PHP国際化プログラミング – マルチバイト、ロケール、書式、タイムゾーン&amp;amp;lt;!–:–&amp;amp;gt;&amp;amp;lt;!–:en–&amp;amp;gt;PHP Internationalization Programming – Multi-Byte, Locale, Format, and Time Zone&amp;amp;lt;!–:–&amp;amp;gt;

ソフトウェア国際化ツールWorld Wide Navi(ワールドワイドナビ)の国際化プログラミング参考情報から、PHPの国際化の抜粋です。

1. マルチバイト
文字日本語のようなマルチバイト文字を扱うためには、mbstringモジュールをWebサーバーにインストールする必要があります。
mb_***()関数はマルチバイト文字の操作を提供し、いくつかのmb_を持たない関数は正しくマルチバイト文字を処理できないため、mb_***()関数に置き換える必要があります。

主な重要関数は以下となります。

===
主なマルチバイト関数の変換
=== (非推称 -> 推称)

mail() -> mb_send_mail()

strlen() -> mb_strlen()
strpos() -> mb_strpos()
strrpos() -> mb_strrpos()
substr() -> mb_substr()
str_replace() -> mb_ereg_replace()
strstr() -> mb_strstr()
strtolower() -> mb_strtolower()
strtoupper() -> mb_strtoupper() 

ereg() -> mb_ereg()
または preg_match()
eregi() -> mb_eregi()
または "i"を使った preg_match()
ereg_replace() -> mb_ereg_replace()
または preg_replace()
eregi_replace() -> mb_eregi_replace()
または "i"を使った preg_replace()
split() -> mb_split() または preg_split()

全てのマルチバイト関数については、
PHPマニュアル -
マルチバイト文字列 関数を参照してください。

全ての非推称の関数については、
PHPマニュアル -
PHP 5.3.x で推奨されない機能
を参照してください。

* mbstring.func_overloadビットフラグを使うことで、非推称の関数のいくつかをオーバーロードされたマルチバイト関数として使用できます。
PHPマニュアル – 関数のオーバーロード機能を参照してください。

2. ユーザーロケールの設定
ユーザーロケール(ユーザーの言語と地域)を日付操作や文化依存の書式(日付、通貨…)に適用させるには、setlocale関数を呼ぶ必要があります。

$locale = "en_US.UTF-8" or "ja_JP.UTF-8"...
これらはHTTPヘッダー(Accept-Language)、
もしくは保存されたアカウント情報から取得する
必要があります。

setlocale(LC_ALL, $locale);
... 全てのロケール対応関数用
例) gettextリソースの切り替え

setlocale(LC_TIME, $locale);
... 日付のローけー屡対応関数用
例) 日付関数の書式の切り替え

3. ユーザー文化に基づくフォーマット
ロケール対応関数はsetlocale関数によってフォーマット(書式)を切り替えることができます。

setlocale(LC_TIME, "en_US.UTF-8");
strftime("%c");
... "Mon 01 Jan 2012..."を返します。
(英語書式)

setlocale(LC_TIME, "ja_JP.UTF-8");
strftime("%c");
... "2012年1月1日..."を返します。
(日本語書式)

*"%c"は、ロケール対応書式のパターンです。

4. サーバーとユーザー間の時間の変換
多言語でグローバル化されたwebサービスで時間を処理するには、GMT/UTCを使うことが推称されます。 date_default_timezone_setを使うことで、全てのユーザー活動を共通時間で管理し、各ユーザーのタイムゾーンに変換することができます。GMT/UTCの処理については、国際化プログラミング- サーバーサイドプログラミングを参照してください。

$timestamp = strtotime(gmdate("Y-m-d H:i:s"));
 ... GMT/UTC タイムスタンプ

date_default_timezone_set("Asia/Tokyo");
... 日本のタイムゾーンを設定
strftime("%c", $timestamp);
... 日本の現地時間を返す

date_default_timezone_set("America/Los_Angeles");
... アメリカのタイムゾーンを設定
strftime("%c", $timestamp);
... アメリカの現地時間を返す

* ユーザーのタイムゾーンはユーザーアカウント情報から取得すべきです。ログインしていないユーザーについては、アクセスIPのエリアか、ユーザーのWebブラウザのJavaScriptで知ることができます。
JavaScriptでのタイムゾーンの取得については、国際化プログラミング- ロケール、書式、タイムゾーン (JavaScriptの章)を参照してください。



&amp;amp;lt;!–:ja–&amp;amp;gt;ソフトウェア国際化ツールWorld Wide Navi PHPサポート追加!&amp;amp;lt;!–:–&amp;amp;gt;&amp;amp;lt;!–:en–&amp;amp;gt;Software i18n Tool World Wide Navi added the support of PHP!&amp;amp;lt;!–:–&amp;amp;gt;

弊社開発の国際化ツール World Wide NaviがPHPのサポートを開始しました!
そのほかに、JavascriptのJSONによる国際化、機能改善なども盛り込まれています!

PHP使いの方はぜひおためしあれ!

ダウンロード:http://www.kokusaika.jp/product/ja/wwnavi.html

フォーラム:http://forum.kokusaika.jp/wwnavi/

また、これに伴い、国際化プログラミングの記事も追加いたしました。
http://www1.kokusaika.jp/advisory/org/ja/top.html

気に入っていただいた方はぜひシェアのほどよろしくお願いします!

Is Your Source Code i18ned?

(個人的に気に入っている今年のフレーズ)