Programmer's Reference Guide
| 導入 |
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(
- 'adapter' => 'Company_Translate_Adapter_MyFormat',
- 'content' => '/path/to/translate.xx',
- 'locale' => 'en',
- '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(
- 'adapter' => 'gettext',
- 'content' => '/path/to/translate.mo',
- 'locale' => 'en'
- )
- );
- // to clear the cache somewhere later in your code
- Zend_Translate::clearCache();
注意: キャッシュの設定は、アダプタや Zend_Translate のインスタンスを使用したり初期化したりする 前 に行わなければなりません。 さもないと、新たなソースを addTranslation() メソッドで追加するまで 翻訳ソースのキャッシュは行われません。
When the attached cache supports tagging you can set a own tag string by using the option tag. This allows you do delete only the cache from this single instance of Zend_Translate. When you are not using this option the default tag Zend_Translate is used.
Using the option tag you must give the used tag to clearCache() to declare which tag you want to delete.
- $cache = Zend_Cache::factory('Core',
- 'File',
- $frontendOptions,
- $backendOptions);
- Zend_Translate::setCache($cache);
- $translate = new Zend_Translate(
- 'adapter' => 'gettext',
- 'content' => '/path/to/translate.mo',
- 'locale' => 'en',
- 'tag' => 'MyTag'
- )
- );
- // somewhere later in your code
- Zend_Translate::clearCache('MyTag');
| 導入 |
Add A Comment
Please do not report issues via comments; use the ZF Issue Tracker.
If you have a JIRA/Crowd account, we suggest you login first before commenting.

Comments
Zend_Translate only except one parameter as an array.
In 10.2 it works like the example.
Lorsqu'on utilise des caractères accentués en ISO-8859... avec le format CSV (sous Excel) et Zend_Translate_Adapter_Csv avec PHP5, l'encodage n'est pas détecté (comme expliqué plus haut) et les accents s'affichent mal.
Il existe une solution simple pour éviter ce problème (en attendant PHP6) :
- Open Office vous permet d'ouvrir des fichiers CSV au format Unicode (UTF-8) ou Europe (ISO-8859-15 par ex) et de les enregistrer avec l'encodage voulu. Il convertit donc les accents automatiquement : par exemple, é en é
Sinon on pourrait surcharger la classe Zend_Translate_Adapter_Csv et y ajouter une méthode utf8_decode par exemple...
De cette façon vous pouvez facilement donner à votre client les traductions et les réintégrer dans votre application.
Cordialement
Hi,
To avoid encoding and UTF_8 character sets problems, with CSV format, you can use Open Office to convert your file into encoding of your choice : UTF_8 to ISO, ISO to UTF_8...
Best regards
as I worked for 7 years as an IT-leader in a translation company I must admitt, that Zend_Translate is a good step, but especially the TMX and XLIFF-Adapters are far away from beeing able to handle TMX and XLIFF-data correctly. Everything works fine as long as you do not have so called inline elements (see oasis xliff spec i. e.). As soon as you need them, i. e. if you have a string to translate like the following:
"'%value%' is now valid resetHash"
it would be necessary i. e. in xliff to wrap the variable-Part in the string in an inline Tag. The reason for this is, that it _has_ to be inside the translated string, because in some languages it for sure must not be placed at the beginning of the sentence, but i. e. in the middle or at the end. Therefore it has to be inside of the translated string, but as a programmer you want to be sure, that the translator for example does not translate the word "value" - but online place the string '%value%' in the correct position. Therefore you have the inline elements in professional translation formats like xliff (which is in reality not more simple as tmx like stated above, but the more standard and more modern but sometimes even complexer format than tmx).
Therefore the sentence above wrapped in an xliff unit shoulld look like the following:
<trans-unit id='uniqId'><source><ph equiv-text='The returned form Value'>'%value%'</ph> is no valid resetHash</source><target><ph equiv-text='The returned form Value'>'%value%'</ph> ist kein gültiger resetHash</target></trans-unit>
But if you do things like that in your xliff-File, the xliff-Adapter of ZF is not able to handle it correctly. What is does is a string to string comparison of the string you have in your Zend_Translate->_(''); expression i. e. Zend_Translate->_("'%value%' is now valid resetHash"); with the string between the source-Tags. To get a match from the adapter for my to be translated string above, the corresponding xliff-source-Tag has to look like this:
<source>'%value%' is no valid resetHash</source>
But this way the variable '%value%' is not protected and therefore likely to be translated in a professional translation process, where translators should be experts in spoken languages but not in programming languages.
Would be great to have support for inline-Tags especially in xliff, which is the future, while TMX is the past.
Regards, Marc
As an example, take a look at MediaWiki projects (Wikipedia too) and TranslateWiki site. They are using PHP arrays and have more than 150 languages and thousands of variables with short and long strings. And I haven't heard any complains.
So, again, please add a real reason next to that above statement.
Thanks