第15章 Zend_Locale
前のページ |  | 次のページ

## 第15章 Zend_Locale

## 15.1. 導入

`Zend_Locale` は、 "ひとつのアプリケーションを世界中で使用するにはどうしたらいいでしょう?" という質問に対するフレームワーク側からの回答です。たいていの人は "かんたんじゃん。出力内容をいくつかの言語に翻訳すればいいんだよ。" と言うでしょう。しかし、ただ単にフレーズを他の言語に置き換えるだけといった 単純な翻訳テーブルでは不十分です。 たとえば姓と名の順番や敬称、そして数値や日付、時刻、通貨などの書式は、 地域によって異なります。

地域化 (Localization) だけでなく、 国際化 (Internationalization) も必要となります。これらは、それぞれ `L10N` および `I18N` と略されることもあります。国際化とは、そのシステムを特定のユーザ集団の (言語、地域、数値書式、財務規約、日付時刻書式などの) ニーズにかかわらず使用できるようにすることを言います。 地域化とは、特定の集団のニーズに対応するために、 システムに明示的なサポートを追加することを言います。 たとえば言語の翻訳や、各地域の規約 (複数形の扱い、日付、時刻、通貨、名前、 記号、並び順など) が該当します。 `L10N` と `I18N` は、お互い補完しあうものです。 Zend Framework では、いくつかのコンポーネントを組み合わせることで これらのサポートを提供しています。たとえば Zend_Locale、Zend_Date、 Zend_Measure、Zend_Translate、Zend_Currency そして Zend_TimeSync といったコンポーネントがあります。

### 15.1.1. 地域化とは

地域化とは、あるアプリケーション (あるいはホームページ) が、さまざまな言語を話すユーザによって使用することができるということです。 しかし、ご存知のとおり、地域化とは単に文字列を翻訳するだけのことではありません。 以下のような内容が含まれます。

- `Zend_Locale` - 他の ZF コンポーネントにおける地域化サポートで対応しているロケールのバックエンドとなります。

- `Zend_Translate` - 文字列を翻訳します。

- `Zend_Date` - 日付や時刻を地域化します。

- `Zend_Calendar` - カレンダーを地域化します (グレゴリオ暦以外の暦もサポートしています)。

- `Zend_Currency` - 通貨を地域化します。

- `Zend_Locale_Format` - 地域化された数値のパースおよび生成を行います。

- `Zend_Locale_Data` - 国名や言語名、そして CLDR にあるさまざまな内容 について、各地域の標準文字列を取得します。

- `TODO` - Localization of collations

### 15.1.2. ロケールとは?

コンピュータのユーザは皆、(気づいていないかもしれませんが) ロケールを使用しています。 地域化をサポートしていないアプリケーションの場合は、 通常は暗黙的に特定のロケール (そのアプリケーションの作者のロケール) を使用しています。 クラスや関数が地域化されていることを、ここでは `ロケールに対応している`ということにします。 そのユーザがどの地域にいるのかを、どうやってコードで知るのでしょうか?

ロケール文字列あるいはロケールを表すオブジェクトを使用して、 `Zend_Locale` およびそのサブクラスはユーザが希望する言語および地域を知ります。 この情報にもとづいて、正しい書式化や正規化、規約を適用します。

### 15.1.3. ロケールの表現方法は?

ロケール識別子に含まれる情報は、ユーザの言語と 地理上の地域 (たとえば自宅あるいは勤務先の属する州など) です。 Zend Framework が使用するロケール識別文字列は、 国際的に定義されている言語と地域の略称で、 `language_REGION` という形式です。 言語および地域は、どちらも二文字の ASCII 文字列となります。

アメリカのユーザの言語は `英語`、そして地域は `アメリカ` です。そこで、ロケール識別子は "en_US" となります。 ドイツのユーザの言語は `ドイツ`、そして地域は `ドイツ` です。そこで、ロケール識別子は "de_DE" となります。 ロケールおよび地域の組み合わせの定義済みの一覧 を参考に、Zend Framework で使用するロケールを選択しましょう。

例 15.1. 特定のロケールの選択

    <?php
    require_once 'Zend_Locale');
    $locale = new Zend_Locale('de_DE'); // ドイツ語 _ ドイツ
    ?>

アメリカに住むドイツ人は、言語は `ドイツ語` で地域は `アメリカ` としたいかも知れません。しかし、このような非標準の組み合わせは、 "ロケール" としては直接サポートしていません。 そのかわりに、もし無効な組み合わせが使用されると、 自動的に地域コードが切り捨てられます。 たとえば "de_IS" は "de" に切り捨てられ、"xh_RU" は "xh" に切り捨てられます。これらの組み合わせは無効だからです。 さらに、言語コードがサポートされていない場合 (例 "zz_US") や存在しない場合は、デフォルトの "root" ロケールを使用します。 "root" ロケールではデフォルトとして、 国際的に認知されている日付、時刻、数値、通過等を定義しています。 この切捨て処理は、要求された情報の内容に依存します。 言語と地域の組み合わせの中には、 特定の型のデータ (たとえば日付) では有効だけれども 別の型 (たとえば通貨) では無効だというものがあるからです。

過去の歴史には注意しましょう。ZF コンポーネントは、 これまでさまざまな場所で変更されてきた過去のタイムゾーンについては対応しません。 たとえば この一覧表 をご覧ください。特定の地域が夏時間を採用するかどうかや、 どのタイムゾーンに属するかなどは、時の政府によって何度も変更されています。 したがって、日付の計算をおこなう際には、 ZF コンポーネントはこれらの変更には対応しません。 その代わりに、現時点の夏時間対応、現時点のタイムゾーンに対応した正しい時刻を使用します。

### 15.1.4. 正しいロケールの選択

たいていの場合は、`new Zend_Locale()` とすると自動的に正しいロケールを選択します。 これはユーザのウェブブラウザから送られてきた情報をもとに判断します。 しかし、`new Zend_Locale(Zend_Locale::ENVIRONMENT)` を使用すると、以下に示すようにホストサーバの環境設定から情報を取得するようになります。

例 15.2. ロケールの自動選択

    <?php
    require_once 'Zend/Locale.php';
    $locale  = new Zend_Locale();
    $locale1 = new Zend_Locale(Zend_Locale::BROWSER);     // デフォルトの挙動で、上と同じです
    $locale2 = new Zend_Locale(Zend_Locale::ENVIRONMENT); // ホストサーバ上の設定を使用します
    $locale3 = new Zend_Locale(Zend_Locale::FRAMEWORK);   // フレームワークアプリケーションのデフォルト設定を使用します
    ?>

`Zend_Locale` がロケールの自動選択に使用する検索アルゴリズムは、 三種類の情報をもとにしています。

1. const `Zend_Locale::BROWSER` - ユーザのウェブブラウザは、リクエストの際に情報を送信します。これは、 PHP のグローバル変数 `HTTP_ACCEPT_LANGUAGE` で取得できます。 対応するロケールが見つからない場合は `ENVIRONMENT` による検索を行い、それでもだめなら最後は `FRAMEWORK` を使用します。

2. const `Zend_Locale::ENVIRONMENT` - PHP は、ホストサーバのロケールを `setlocale()` 関数で取得します。 対応するロケールが見つからない場合は FRAMEWORK による検索を行い、 それでもだめなら最後は BROWSER を使用します。

3. const `Zend_Locale::FRAMEWORK` - Zend Framework がコンポーネントのデフォルトを指定できる仕組みが定まったら (予定されていますが、現在はまだありません)、 この定数を使用することでデフォルト設定を選択できるようになります。 対応するロケールが見つからない場合は `ENVIRONMENT` による検索を行い、それでもだめなら最後は `FRAMEWORK` を使用します。

### 15.1.5. ZF のロケール対応のクラス

ZF では、ロケール対応のクラスは `Zend_Locale` を使用しています。そして、上で説明したように自動的にロケールを選択します。 たとえば、ZF のウェブアプリケーションで `Zend_Date` を使用して日付を作成すると、何もロケールを指定しなくても ユーザのウェブブラウザの設定からロケール情報を取得してそれを使用します。

例 15.3. 日付のデフォルトが、ウェブのユーザのロケールになる例

    <?php
    require_once 'Zend/Date.php';
    $date = new Zend_Date('2006',Zend_Date::YEAR);
    ?>

このデフォルトを上書きし、ロケール対応の ZF コンポーネントでウェブサイトの訪問者の設定にかかわらず特定のロケールを指定するには、 コンストラクタの三番目の引数でロケールを明示的に指定します。

例 15.4. デフォルトのロケール選択のオーバーライド

    <?php
    require_once 'Zend/Date.php';
    require_once 'Zend/Measure.php';

    $usLocale = new Zend_Locale('en_US');
    $date = new Zend_Date('2006',Zend_Date::YEAR, $usLocale);
    $temp = new Zend_Measure('100,10',Zend_Measure::TEMPERATURE, $usLocale);
    ?>

多くのオブジェクトですべて同一のデフォルトロケールを使用することがわかっている場合は、 それを明示的に指定すると、毎回デフォルトロケールを検索することによる オーバーヘッドを回避することができます。

例 15.5. デフォルトのロケールを使用する際のパフォーマンスの最適化

    <?php
    require_once 'Zend/Date.php';
    require_once 'Zend/Measure.php';

    $locale = new Zend_Locale();
    $date = new Zend_Date('2006',Zend_Date::YEAR, $locale);
    $temp = new Zend_Measure('100,10',Zend_Measure::TEMPERATURE, $locale);
    ?>

前のページ |  | 次のページ
14.3. JSON オブジェクト | ホーム | 15.2. Zend_Locale の使用法