この章では、PHPおよびOracle Database環境でのグローバル・アプリケーションの開発について説明します。グローバルなインターネット・アプリケーションの開発およびデプロイに関連付けられている基本的なタスク(ロケール認識の開発、ユーザー選択言語でのHTMLコンテンツの構築、ユーザーのロケールの表記規則に従ったデータの表示など)について説明します。
様々なロケールがサポートされているグローバルなインターネット・アプリケーションを構築するには、優れた開発プラクティスが必要です。ロケールとは、各国語およびその言語が話されている地域のことです。アプリケーション自体がユーザーのロケール・プリファレンスを認識し、ユーザーが考えているとおりの表記規則に従ってコンテンツを表示できる必要があります。適切なロケール特性(正しい日付書式や数値書式など)でデータを表示することが重要です。Oracle Databaseは、完全な国際化を実現しており、グローバル・アプリケーションを開発およびデプロイするためのグローバルなプラットフォームを提供します。
この章の内容は次のとおりです。
グローバル・アプリケーションを構築するための最初の手順は、PHPエンジンとOracle Databaseの間に接続を正しく設定する手順です。これで、すべての層にわたってデータ整合性が保証されます。インターネット・ベースのほとんどの標準規格で、文字エンコーディングとしてUnicodeがサポートされているため、この章ではデータ交換用のキャラクタ・セットとしてUnicodeを使用します。
PHPはOCI8拡張モジュールを使用するため、OCIに適用されるルールはPHPにも適用されます。Oracleロケールの動作(OCIアプリケーションで使用されるクライアント・キャラクタ・セットを含む)は、NLS_LANG
環境変数で定義します。この環境変数の形式は次のとおりです。
<language>_<territory>.<character set>
たとえば、ドイツのドイツ語ユーザーがUnicodeでアプリケーションを実行している場合、NLS_LANG
は次のように設定されています。
GERMAN_GERMANY.AL32UTF8
言語および地域の設定によって、Oracle日付書式、エラー・メッセージ言語、ソート順序に使用されるルールなどのOracleの動作が制御されます。キャラクタ・セットAL32UTF8は、UTF-8のOracle名です。
NLS_LANG
環境変数の詳細は、Oracle Databaseのインストレーション・ガイドを参照してください。
PHPがApacheにインストールされている場合は、/etc/profile
にNLS_LANG
を設定できます。
export NLS_LANG GERMAN_GERMANY.AL32UTF8
PHPがOracle HTTP Serverにインストールされている場合は、$ORACLE_HOME/opmn/conf/opmn.xml
に環境変数としてNLS_LANG
を設定する必要があります。
<ias-component id="HTTP_Server"> <process-type id="HTTP_Server" module-id="OHS"> <environment> <variable id="PERL5LIB" value="D:\oracle\1012J2EE\Apache\Apache\mod_perl\site\5.6.1\lib"/> <variable id="PHPRC" value="D:\oracle\1012J2EE\Apache\Apache\conf"/> <variable id="NLS_LANG" value="german_germany.al32utf8"/> </environment> <module-data> <category id="start-parameters"> <data id="start-mode" value="ssl-disabled"/> </category> </module-data> <process-set id="HTTP_Server" numprocs="1"/> </process-type> </ias-component>
この変更を実装するには、Webリスナーを再起動する必要があります。
PHPは、ISO-8859-1キャラクタ・セットで動作するように設計されています。それ以外のキャラクタ・セット(特にマルチバイト・キャラクタ・セット)を処理する場合は、一連のマルチバイト文字列関数を使用できます。これらの機能を有効にするには、mbstring拡張モジュールを有効にする必要があります。
アプリケーション・コードでmb_strlen()
などの関数を使用して、文字列内の文字数を計算する必要があります。これによって、文字列内のバイト数を戻すstrlen()
とは異なる値が戻される場合があります。
mbstring拡張モジュールを有効にし、Webサーバーを再起動すると、いくつかの構成オプションを使用できるようになります。mbstring.func_overload
をOverload設定のいずれかに設定して、標準のPHP文字列関数の動作を変更できます。
詳細は、PHPのmbstringに関する次のリファレンス・マニュアルを参照してください。
グローバル環境のアプリケーションでは、ロケール・プリファレンスが異なるユーザーに対応する必要があります。ユーザーの優先ロケールを決定した後は、そのロケールの言語でHTMLコンテンツを構築し、そのロケールの表記規則に従います。
ユーザーのロケールを決定する一般的な方法として、ブラウザのデフォルトのISOロケール設定を使用する方法があります。通常、ブラウザは、Accept Language HTTPヘッダーでHTTPサーバーにそのロケール・プリファレンス設定を送信します。Accept Language HTTPヘッダーがNULLの場合は、使用可能なロケール・プリファレンス情報がなく、事前定義のデフォルトのロケールにフォールバックされます。
次のPHPコードは、$_SERVER
サーバー変数を使用して、Accept Language HTTPヘッダーからISOロケールを取り出します。
$s = $_SERVER["HTTP_ACCEPT_LANGUAGE"]
ユーザーのロケール・プリファレンスを決定すると、日付、時間、通貨の書式などのロケール依存の関数をコールして、ロケールの表記規則に従ってHTMLページを書式設定できます。
様々なプログラミング環境で実装されるグローバル・アプリケーションを構築する場合は、異なる環境間でユーザー・ロケール設定を同期できるようにする必要があります。たとえば、PL/SQLプロシージャをコールするPHPアプリケーションでは、PL/SQLプロシージャをコールする前に、ISOロケールを対応するNLS_LANGUAGE
値およびNLS_TERRITORY
値にマップし、ユーザーのロケールに合わせてパラメータ値を変更する必要があります。PL/SQL UTL_I18Nパッケージには、ISOロケールとOracleロケール間でマップできるマッピング関数が含まれています。
表8-1に、よく使用されるロケールをISO環境およびOracle環境に定義する方法を示します。
表 8-1: ISO、SQL、PL/SQLの各プログラミング環境でのロケールの表現
ロケール | ロケールID | NLS_LANGUAGE | NLS_TERRITORY |
---|---|---|---|
中国語(中華人民共和国) |
zh-CN |
SIMPLIFIED CHINESE |
CHINA |
中国語(台湾) |
zh-TW |
TRADITIONAL CHINESE |
TAIWAN |
英語(アメリカ合衆国) |
en-US |
AMERICAN |
AMERICA |
英語(イギリス) |
en-GB |
ENGLISH |
UNITED KINGDOM |
フランス語(カナダ) |
fr-CA |
CANADIAN FRENCH |
CANADA |
フランス語(フランス) |
fr-FR |
FRENCH |
FRANCE |
ドイツ語 |
de |
GERMAN |
GERMANY |
イタリア語 |
it |
ITALIAN |
ITALY |
日本語 |
ja |
JAPANESE |
JAPAN |
韓国語 |
ko |
KOREAN |
KOREA |
ポルトガル語(ブラジル) |
pt-BR |
BRAZILIAN PORTUGUESE |
BRAZIL |
ポルトガル語 |
pt |
PORTUGUESE |
PORTUGAL |
スペイン語 |
es |
SPANISH |
SPAIN |
HTMLページのエンコーディングは、ブラウザおよびインターネット・アプリケーションに関する重要な情報です。ページ・エンコーディングは、インターネット・アプリケーションがサービスを提供しているロケールで使用されるキャラクタ・セットとみなすことができます。ブラウザは、正しいフォントおよびキャラクタ・セットのマッピング表を使用してHTMLページを表示できるように、ページ・エンコーディングを認識している必要があります。インターネット・アプリケーションは、HTMLフォームに入力されたデータを処理できるように、HTMLページ・エンコーディングを認識している必要があります。
ロケールごとに異なるネイティブ・エンコーディングを使用するのではなく、すべてのページ・エンコードでUTF-8(Unicodeエンコーディング)を使用することをお薦めします。このエンコーディングを使用すると、グローバル・アプリケーションのコーディングを簡略化できるのみでなく、単一ページに多言語コンテンツを配置できます。
HTMLページのエンコーディングをHTTPヘッダーまたはHTMLページ・ヘッダーに指定できます。
HTMLページ・エンコーディングをHTTPヘッダーに指定するには、HTTP仕様にContent-Type HTTPヘッダーを含めます。このヘッダーで、コンテンツ・タイプおよびキャラクタ・セットを指定します。Content-Type HTTPヘッダーの形式は次のとおりです。
Content-Type: text/html; charset=utf-8
charsetパラメータで、HTMLページのエンコーディングを指定します。charsetパラメータに指定可能な値は、ブラウザでサポートされている文字エンコーディングのIANA名です。
この方法は、主に静的なHTMLページに使用します。HTMLページ・エンコーディングをHTMLページ・ヘッダーに指定するには、文字エンコーディングを次のようにHTMLヘッダーに指定します。
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
charsetパラメータで、HTMLページのエンコーディングを指定します。Content-Type HTTPの場合と同様に、charsetパラメータに指定可能な値は、ブラウザでサポートされている文字エンコーディングのIANA名です。
ユーザー・インタフェースをユーザーのローカル言語で使用できるようにすることは、アプリケーションのグローバル化の基本的なタスクです。HTMLページのコンテンツの翻訳可能なソースは、次のように分類されます。
アプリケーション・コードに含まれているテキスト文字列
静的なHTMLファイル、イメージ・ファイル、およびCSSなどのテンプレート・ファイル
データベースに格納されている動的なデータ
PHPアプリケーション・ロジック内の翻訳可能な文字列を外部化して、そのテキストを簡単に翻訳できるようにする必要があります。これらのテキスト・メッセージは、翻訳対象データのタイプおよびボリュームに応じて、フラット・ファイルまたはデータベース表に格納できます。
アプリケーションのデータは、ユーザーが考えているとおりに表示される必要があります。そうでない場合、データの意味が誤って解釈される可能性があります。たとえば、12/11/05という日付は、アメリカ合衆国では2005年12月11日を意味するのに対して、イギリスでは2005年11月12日を意味します。ユーザーの数値書式および通貨書式にも同様の違いが存在します。たとえば、.という記号はアメリカ合衆国では小数点セパレータですが、ドイツでは千単位セパレータです。
各言語に独自のソート・ルールがあります。アルファベットの文字の順序に従う言語、文字の画数に従う言語、単語の発音に従う言語などがあります。ユーザーが慣れている言語順序でソートされていないデータを表示すると、情報の検索が難しくなり、時間がかかることがあります。
アプリケーション・ロジックおよびデータベースから取り出すデータの量によっては、アプリケーション・レベルではなくデータベース・レベルでデータを書式設定した方がより適切な場合があります。Oracle Databaseには、ユーザーのロケール・プリファレンスがわかっている場合にデータの表示を調整するのに役立つ機能が多く用意されています。以降の項では、SQLでのロケール依存の操作の例を示します。
Oracle Databaseの日付表示書式には、標準の日付、短い日付、長い日付の3種類があります。次の例では、アメリカ合衆国およびドイツでの短い日付書式と長い日付書式の違いを示します。
SQL> alter session set nls_territory=america nls_language=american; Session altered. SQL> select employee_id EmpID, 2 substr(first_name,1,1)||'.'||last_name "EmpName", 3 to_char(hire_date,'DS') "Hiredate", 4 to_char(hire_date,'DL') "Long HireDate" 5 from employees 6* where employee_id <105; EMPID EmpName Hiredate Long HireDate ---------- --------------------------- ---------- ----------------------------- 100 S.King 06/17/1987 Wednesday, June 17, 1987 101 N.Kochhar 09/21/1989 Thursday, September 21, 1989 102 L.De Haan 01/13/1993 Wednesday, January 13, 1993 103 A.Hunold 01/03/1990 Wednesday, January 3, 1990 104 B.Ernst 05/21/1991 Tuesday, May 21, 1991
SQL> alter session set nls_territory=germany nls_language=german; Session altered. SQL> select employee_id EmpID, 2 substr(first_name,1,1)||'.'||last_name "EmpName", 3 to_char(hire_date,'DS') "Hiredate", 4 to_char(hire_date,'DL') "Long HireDate" 5 from employees 6* where employee_id <105; EMPID EmpName Hiredate Long HireDate ---------- --------------------------- -------- ------------------------------ 100 S.King 17.06.87 Mittwoch, 17. Juni 1987 101 N.Kochhar 21.09.89 Donnerstag, 21. September 1989 102 L.De Haan 13.01.93 Mittwoch, 13. Januar 1993 103 A.Hunold 03.01.90 Mittwoch, 3. Januar 1990 104 B.Ernst 21.05.91 Dienstag, 21. Mai 1991
次の例では、アメリカ合衆国とドイツでの小数点文字およびグループ・セパレータの違いを示します。
SQL> alter session set nls_territory=america; Session altered. SQL> select employee_id EmpID, 2 substr(first_name,1,1)||'.'||last_name "EmpName", 3 to_char(salary, '99G999D99') "Salary" 4 from employees 5* where employee_id <105 EMPID EmpName Salary ---------- --------------------------- ---------- 100 S.King 24,000.00 101 N.Kochhar 17,000.00 102 L.De Haan 17,000.00 103 A.Hunold 9,000.00 104 B.Ernst 6,000.00 SQL> alter session set nls_territory=germany; Session altered. SQL> select employee_id EmpID, 2 substr(first_name,1,1)||'.'||last_name "EmpName", 3 to_char(salary, '99G999D99') "Salary" 4 from employees 5* where employee_id <105 EMPID EmpName Salary ---------- --------------------------- ---------- 100 S.King 24.000,00 101 N.Kochhar 17.000,00 102 L.De Haan 17.000,00 103 A.Hunold 9.000,00 104 B.Ernst 6.000,00
スペイン語では、伝統的にch、llおよびñが一意の文字として扱われ、それぞれc、lおよびnの後に順序付けられます。次の例では、ChenとChungという従業員名にスペイン語のソートを使用した場合の結果を示します。
SQL> alter session set nls_sort=binary; Session altered. SQL> select employee_id EmpID, 2 last_name "Last Name" 3 from employees 4 where last_name like 'C%' 5* order by last_name EMPID Last Name ---------- ------------------------- 187 Cabrio 148 Cambrault 154 Cambrault 110 Chen 188 Chung 119 Colmenares 6 rows selected. SQL> alter session set nls_sort=spanish_m; Session altered. SQL> select employee_id EmpID, 2 last_name "Last Name" 3 from employees 4 where last_name like 'C%' 5* order by last_name EMPID Last Name ---------- ------------------------- 187 Cabrio 148 Cambrault 154 Cambrault 119 Colmenares 110 Chen 188 Chung 6 rows selected.
NLS_LANGUAGE
パラメータは、データベースから戻されるデータベース・エラー・メッセージの言語も制御します。SQL文を発行する前にこのパラメータを設定すると、言語固有のデータベース・エラー・メッセージがアプリケーションに戻されるようになります。
次のサーバー・メッセージについて考えてみます。
ORA-00942: table or view does not exist
NLS_LANGUAGE
パラメータをフランス語に設定すると、このサーバー・メッセージは次のように表示されます。
ORA-00942: table ou vue inexistante
Oracle Databaseのグローバリゼーション・サポート機能の詳細は、『Oracle Database 2日で開発者ガイド』のグローバル環境での作業に関する項を参照してください。