# Zend_Translate のアダプタ

`Zend_Translate` は、さまざまなアダプタを使用して翻訳を行えます。 それぞれのアダプタによって利点や欠点があります。 以下に、翻訳の入力ファイルとしてサポートしているすべてのアダプタについてまとめます。

## `Zend_Translate` のアダプタ

アダプタ | 説明 | 備考
--- | --- | ---
Array | PHP の配列 | 小さめのページ。簡単に使用できる。プログラマしかさわれない。
Csv | カンマ区切りファイル (*.csv/*.txt) | シンプルなテキスト形式。高速。Unicode 文字で問題が発生する可能性がある。
Gettext | gettext のバイナリファイル (*.mo) | linux における GNU の標準形式。スレッドセーフ。翻訳用ツールが必要。
Ini | シンプルな ini ファイル (*.ini) | シンプルなテキスト形式。高速。Unicode 文字で問題が発生する可能性がある。
Tbx | termbase 変換ファイル (*.tbx/*.xml) | アプリケーション間で専門用語を変換するための業界標準。XML フォーマット。
Tmx | tmx ファイル (*.tmx/*.xml) | アプリケーション間での翻訳の業界標準。XML フォーマット。可読形式。
Qt | qt 言語ファイル (*.ts) | クロスプラットフォームなアプリケーションフレームワーク。XML フォーマット。可読形式。
Xliff | xliff ファイル (*.xliff/*.xml) | TMX に似ているが、よりシンプル。XML フォーマット。可読形式。
XmlTm | xmltm ファイル (*.xml) | XML ドキュメントの翻訳メモリの業界標準。XML フォーマット。可読形式。
その他 | *.sql | 今後、その他さまざまなアダプタを実装する予定です。

## 使用するアダプタを決める方法

`Zend_Translate` でどのアダプタを使用するのかを決める必要があります。 プロジェクトの制約や顧客からの要望などの外的要因でアダプタが決まることもよくありますが、 もしあなたに決定権があるのなら、以下のヒントを参考にしてください。

使用するアダプタを決めるにあたっては、 使用するエンコーディングを考慮しなければなりません。 Zend Framework では UTF-8 をデフォルトのエンコーディングとしていますが、 時には他のエンコーディングを使わなければならないこともあるでしょう。 `Zend_Translate` は、 ソースファイル内で定義されているエンコーディングを変更しません。 つまり、もし Gettext のソースが ISO-8859-1 で作られている場合は、 それをそのままのエンコーディングで返します。 ただ、ひとつだけ制限があります。

TMX や XLIFF といった XML ベースのソース形式を使用する場合は、 そのエンコーディングを XML ファイルのヘッダで定義しなければなりません。 エンコーディングの定義がない XML ファイルは、 デフォルトでは UTF-8 として扱われるからです。 また、もうひとつ注意すべき点は、XML ファイルのエンコーディングとして使用できるのは PHP がサポートしているエンコーディングのみであること、 つまり UTF-8、ISO-8859-1 および US-ASCII だけであるということです。

### Zend_Translate_Adapter_Array

Array アダプタは、プログラマにとっては 一番シンプルに使えるアダプタです。 しかし、翻訳する文字列が大量にある場合や 多くの言語に翻訳する必要がある場合は、別のアダプタを使うようにしましょう。 たとえば、翻訳文字列が 5000 ほどある場合は Array アダプタは選択しないほうがいいでしょう。

このアダプタを使うのは、小さめのサイトで少なめの言語を扱い、 かつプログラマ自身で翻訳も行う場合だけにしましょう。

### Zend_Translate_Adapter_Csv

Csv アダプタは、顧客にとっては最もシンプルに使えるアダプタです。 CSV ファイルは標準的なテキストエディタで読むことができますが、 エディタによっては utf8 文字セットをサポートしていないものもあります。

このアダプタを使うのは、 顧客が自分で翻訳を行いたいという場合だけにしましょう。

Csv ファイルのエンコードがあなたの環境のロケール設定と異なる場合、 Csv アダプタで問題が発生することに注意しましょう。 これは PHP 自体のバグによるもので、このバグは PHP 6.0 で修正される予定です (http://bugs.php.net/bug.php?id=38471)。 したがって、Csv アダプタを使用する場合は (PHP の制約のせいで) それがロケール対応でないということに注意しなければなりません。

### Zend_Translate_Adapter_Gettext

Gettext アダプタは、最もよく用いられるアダプタです。 Gettext は GNU が提供している翻訳フォーマットで、世界中で使用されています。 可読形式ではありませんが、便利なフリーウェア (POEdit など) が公開されています。 `Zend_Translate` の Gettext アダプタは、PHP の gettext 拡張モジュールを使わずに実装しています。 PHP の gettext 拡張モジュールをインストールしていなくても Gettext アダプタを使用することが可能です。 また、このアダプタはスレッドセーフですが、PHP の gettext 拡張モジュールは現状ではスレッドセーフでありません。

ほとんどの人たちは、このアダプタを使うことになるでしょう。 便利なツールを使用することで、高品質な翻訳が簡単に作成できます。 しかし、gettext のデータは機械が読める形式で保存されるので、 何らかのツールがないと人間が読むことはできません。

### Zend_Translate_Adapter_Ini

Ini アダプタは非常にシンプルなアダプタであり、 顧客が直接触ることができます。 INI ファイルは標準的なテキストエディタで読むことができますが、 エディタによっては utf8 文字セットをサポートしていないものもあります。

このアダプタを使うのは、 顧客が自分で翻訳を行いたいという場合だけにしましょう。 汎用的な翻訳ソースとしては使用しないようにしましょう。

#### PHP 5.3 でのリグレッション

PHP 5.3 より前のバージョンでは、`parse_ini_file()` および `parse_ini_string()` で INI オプションのキーに非 ASCII 文字を問題なく使用できました。 しかし PHP 5.3 以降では、 非 ASCII 文字のキーはどちらの関数の返す配列からも黙って抜け落ちてしまいます。 UTF-8 や Latin-1 の文字をキーに使用している場合は、 INI アダプタを使うと翻訳が正しく機能しなくなってしまいました。 そのような場合は別のアダプタを使用することを推奨します。

### Zend_Translate_Adapter_Tbx

Tbx アダプタは、内部ですでに TBX フォーマットの翻訳システムを使用している顧客などが使用します。 Tbx は標準の翻訳フォーマットではありませんが、 すでに多くの翻訳や翻訳済み文字列が存在します。 このアダプタを使用する場合は、 必要な文字列をすべて翻訳しなければならないことに気をつけましょう。 TBX は、まったく新しく作られた XML ベースのフォーマットです。 XML ファイルは人間が読むことも可能ですが、 パース速度は gettext ファイルより遅くなります。

このアダプタは、すでにこの形式の翻訳ファイルを持っている企業に最適です。 ファイルは可読形式で、システムに依存しない形式になります。

### Zend_Translate_Adapter_Tmx

Tmx アダプタは、複数のシステムで同一の翻訳ソースを使用している顧客などが使用します。 また、翻訳ソースをシステムに依存しない形式にしたい場合にも使用します。 TMX は XML 形式のフォーマットで、業界標準になるといわれています。 XML ファイルは人間が読むことも可能ですが、 パース速度は gettext ファイルより遅くなります。

中規模から大規模の会社はこのアダプタを使用します。 ファイルは可読形式で、システムに依存しない形式になります。

### Zend_Translate_Adapter_Qt

Qt アダプタは、QtLinguist で作成した TS ファイル形式の翻訳を使用している顧客が使用します。 QT は XML 形式のフォーマットです。 XML ファイルは人間が読むことも可能ですが、 パース速度は gettext ファイルより遅くなります。

大手企業の中には QT フレームワークを使用したソフトウェアを作成しているところがあります。 ファイルは可読形式で、システムに依存しない形式になります。

### Zend_Translate_Adapter_Xliff

Xliff アダプタは、XML ファイルを使用したいけれど TMX 用のツールを持っていないという顧客などが使用します。 XLIFF は XML 形式のフォーマットで、 TMX と関連していますがもうすこしシンプルです。機能も一部限定されています。 XML ファイルは人間が読むことも可能ですが、 パース速度は gettext ファイルより遅くなります。

中規模の会社はこのアダプタを使用します。 ファイルは可読形式で、システムに依存しない形式になります。

### Zend_Translate_Adapter_XmlTm

XmlTm アダプタは、すでにこのレイアウトを採用している顧客が使用するアダプタです。 XmlTm は、html ソース全体を翻訳ソースに含めることのできるフォーマットで、 翻訳とレイアウトがひとつにまとまります。 XLIFF は XML ベースのフォーマットです。XLIFF と関連していますが、それほど読みやすくはありません。

このアダプタは、すでにソースファイルが存在する場合にのみ使用するようにしましょう。 ファイルは可読形式で、システムに依存しない形式になります。

## 自作のアダプタの組み込み

`Zend_Translate` に、自作のアダプタクラスを組み込むこともできます。 これは、`Zend_Translate` に組み込まれている標準のアダプタクラスと同様に使うことができます。

`Zend_Translate` で使用するアダプタクラスは、 `Zend_Translate_Adapter` のサブクラスでなければなりません。 `Zend_Translate_Adapter` は抽象クラスであり、翻訳に必要なものをすべて定義しています。 あなたがすべきことは、翻訳データの読み込み方法を定義することだけです。

名前の先頭に "Zend" をつけることができるのは Zend_Framework 内のパッケージだけです。`Zend_Translate` で使うためのアダプタを自作する場合は、 その名前はたとえば "Company_Translate_Adapter_MyFormat" のようにする必要があります。 次のコードは、独自のアダプタクラスを実装する例を示すものです。

    try {
        $translate = new Zend_Translate('Company_Translate_Adapter_MyFormat',
                                        '/path/to/translate.xx',
                                        'en',
                                        array('myoption' => 'myvalue'));
    } catch (Exception $e) {
        // ファイルが見つからない、アダプタクラスが存在しない、……
        // などの一般的なエラー
    }

## 全アダプタの高速化

`Zend_Translate` では、内部的に `Zend_Cache` を使用して翻訳ソースの読み込みを高速化できます。 これは、多数の翻訳ソースを使用していたり XML ベースの複雑なソース形式を使用していたりする場合に非常に便利です。

キャッシュ機能を使用するには、キャッシュオブジェクトを `Zend_Translate::setCache()` メソッドで渡します。 このメソッドの唯一のパラメータには `Zend_Cache` のインスタンスを指定します。 また、任意のアダプタを直接使用するには `setCache()` メソッドを使用します。 利便性を考慮して、静的メソッド `getCache()`、`hasCache()`、`clearCache()` および `removeCache()` も用意されています。

    $cache = Zend_Cache::factory('Core',
                                 'File',
                                 $frontendOptions,
                                 $backendOptions);
    Zend_Translate::setCache($cache);
    $translate = new Zend_Translate('gettext',
                                    '/path/to/translate.mo',
                                    'en');

キャッシュの設定は、アダプタや `Zend_Translate` のインスタンスを使用したり初期化したりする 前 に行わなければなりません。 さもないと、新たなソースを `addTranslation()` メソッドで追加するまで 翻訳ソースのキャッシュは行われません。