マルチバイト文字列関数(mbstring)
マルチバイト文字列
&reftitle.intro;
全ての文字をシングルバイトで一対一表現可能な言語は数多くありますが、
文字表現に単一バイトによる表現範囲を越えるほど多くの文字を必要とする
言語も多くあります。マルチバイト文字のエンコーディング法は、
こうした(256を越える)多くの文字を通常のビット単位の符号化システムで表現するために
開発されました。
マルチバイトエンコーディングで符号化された文字列を(trim, split, splice,などで)
処理する際、こうしたエンコーディングでは二つ以上の連続するバイトが一つの文字を表す
可能性があるため、特別な関数を使用する必要があります。
マルチバイトに対応しない文字列関数を文字列に適用した場合、マルチバイト文字の
先頭バイトまたは終了バイトを検出できずに文字列を壊し、多くの場合には元の意味を
失わせてしまう可能性があります。
mbstringは、これらのマルチバイト対応関数を
提供し、マルチバイトエンコーディング、シングルバイトエンコーディングの処理を
基本的に前提とするPHPで処理することを容易にします。
これに加えて、mbstring は、複数のエンコーディング間での
文字エンコーディング変換を行います。
mbstringは、もともと日本語のWebページで使用する
ために開発されましたが、UTF-8やUCS-2のようなUnicodeに基づく
エンコーディングや多くの(以下に示す)シングルバイトエンコーディングも処理する
ことが可能です。
PHPの文字エンコーディングに関する要件
以下の型のエンコーディングが、PHPで安全に使用することができます。
シングルバイトエンコーディングで、
00hから 7fhの範囲の文字に関して、
ASCII互換(ISO646互換)のマッピングを有する。
マルチバイトエンコーディングで、
00hから 7fhの範囲の文字では、
ASCII互換のマッピングを有する。
ISO2022エスケープシーケンスを使用しない。
単一の文字を表す複数バイトのいずれにおいても
00hから7fhの
値を使用しない。
PHPで動作しないと思われる文字エンコーディングの例を以下に示します。
これらのエンコーディングで書かれたPHPスクリプトは、
特に符号化された文字列がスクリプトで記述子やリテラルに使用される場合には、
動作しない可能性がありますが、入力されるHTTPクエリに関して
mbstringの透過的なエンコーディングフィルタを
設定することでこれらのエンコーディングをほとんど使用しないようにすることが
できます。
SJIS, BIG5, CP936, CP949, GB18030 は、読者がパーサ/コンパイラ、
文字エンコーディングと文字エンコーディングの問題点について精通していない限り
内部エンコーディングとして使用するべきではありません。
PHPでデータベースを使用する場合、性能を向上させるためにデータベースとPHPの
内部エンコーディングについて同じ文字エンコーディングを使用することを推奨します。
PostgreSQLを使用している場合、バックエンドの文字エンコーディング
と異なる文字エンコーディングを使用することが可能です。詳細につい
ては、PostgreSQLのマニュアルを参照ください。
&reference.mbstring.configure;
&reference.mbstring.ini;
&reftitle.resources;
&no.resource;
&reference.mbstring.constants;
HTTP入出力
HTTP 入出力の文字エンコーディング変換はバイナリデータも変換して
しまいます。HTTP入出力にバイナリデータが使用される場合、ユーザは、
文字エンコーディング変換を制御する必要があります。
PHP 4.3.2およびそれ以前のバージョンの場合、
HTMLフォームのenctypeが
multipart/form-dataに設定された場合、
mbstring は、POSTデータの文字エンコーディング
を変換しません。この場合、文字列を内部文字エンコーディングに変換
してやる必要があります。
PHP 4.3.3以降、HTMLフォームのenctypeが
multipart/form-dataに設定され、かつ、
&php.ini;において
mbstring.encoding_translationにOnが指定されて
いる場合、
POSTデータの変数とアップロードされたファイルの名前の
文字エンコーディングは、内部文字エンコーディングに変換されます。
ただし、クエリキーに関しては、変換されません。
HTTP入力
PHPスクリプトでHTTP入力文字変換を制御する手段はありません。
HTTP入力文字変換を無効にするには、&php.ini;
で行う必要があります。
&php.ini;でHTTP入力変換を無効にする
PHPをApacheモジュールで使用する場合、PHP iniの設定を
&httpd.conf; により仮想ホスト単位で、または
&htaccess; によりディレクトリ単位で上書きすることが可能です。
詳細は、設定の節および
Apacheマニュアルを参照ください。
HTTP出力
出力の文字エンコーディング変換を有効にする方法は複数あります。
一つ目は &php.ini;、もう1つは
ob_start で ob_start
のコールバック関数として
mb_output_handler を指定するものです。
PHP3-i18nのユーザにとっては、mbstringの出
力変換は、PHP3-i18nとは異なっています。文字エンコーディング
は、出力のバッファリング機能を使用して変換されます。
&php.ini; の設定例
スクリプトの例
]]>
サポートされる文字エンコーディング
現在、以下の文字エンコーディングがmbstringモ
ジュールによりサポートされています。文字エンコーディングは、
mbstring関数のencodingパラ
メータで指定することが可能です。
以下の文字エンコーディングがこのPHPエクステンションでサポートされ
ています。
UCS-4
UCS-4BE
UCS-4LE
UCS-2
UCS-2BE
UCS-2LE
UTF-32
UTF-32BE
UTF-32LE
UTF-16
UTF-16BE
UTF-16LE
UTF-7
UTF7-IMAP
UTF-8
ASCII
EUC-JP
SJIS
eucJP-win
SJIS-win
ISO-2022-JP
JIS
ISO-8859-1
ISO-8859-2
ISO-8859-3
ISO-8859-4
ISO-8859-5
ISO-8859-6
ISO-8859-7
ISO-8859-8
ISO-8859-9
ISO-8859-10
ISO-8859-13
ISO-8859-14
ISO-8859-15
byte2be
byte2le
byte4be
byte4le
BASE64
HTML-ENTITIES
7bit
8bit
EUC-CN
CP936
HZ
EUC-TW
CP950
BIG-5
EUC-KR
UHC (CP949)
ISO-2022-KR
Windows-1251 (CP1251)
Windows-1252 (CP1252)
CP866 (IBM866)
KOI8-R
&php.ini;のエントリではエンコーディング名を指定可能ですが、
"auto" および
"pass" も指定可能です。
mbstring 関数には、エンコーディング名と
"auto" を指定可能です。
"pass" が指定された場合、文字エンコー
ディング変換は行われません。
"auto" が指定された場合、この文字列
は、"ASCII,JIS,UTF-8,EUC-JP,SJIS"に
変換されます。
mb_detect_orderも参照ください。
マルチバイト対応版関数による既存関数のオーバーロード
PHPアプリケーションの多くは、英語等のシングルバイトの言語用に設計
されており、日本語を含むマルチバイト文字列を扱う場合には問題を生
じる場合があります。substr等のPHPの文字列関
数の多くはマルチバイト文字列に対応していません。
マルチバイト拡張モジュール(mbstring)では、文字列を処理するPHP関数
のマルチバイト対応版(例えば、substrの場合は
mb_substr)をサポートしています。
マルチバイト拡張モジュール(mbstring)では、PHP 4.2.0以降で既存の
PHP関数を対応するマルチバイト文字対応版の関数でオーバーロードする
機能をサポートします。関数のオーバーロードを行うと、例えば
substrをPHPスクリプトでコールした場合に、
mb_substrが代わりにコールされるようになりま
す。これにより、マルチバイト文字に対応しないアプリケーションの移
植が容易となります。
関数オーバーロードを使用するには、設定ファイル php.iniの
mbstring.func_overloadディレクティブに0以外の
値を設定します。設定値によりオーバーロードされる関数の種類が異な
ります。メール関数の場合は1、文字列関数は2、正規表現関数は4を使用
します。論理和をとることにより複数の値を指定可能です。例えば、7を
指定すると全てのメール、文字列、正規表現関数をオーバーロードしま
す。オーバーロードされる関数を下表に示します。
オーバーロードされる関数
mbstring.func_overloadの値
元の関数
オーバーロードする関数
1
mail
mb_send_mail
2
strlen
mb_strlen
2
strpos
mb_strpos
2
strrpos
mb_strrpos
2
substr
mb_substr
4
ereg
mb_ereg
4
eregi
mb_eregi
4
ereg_replace
mb_ereg_replace
4
eregi_replace
mb_eregi_replace
4
split
mb_split
ディレクトリ単位の設定でこの関数オーバーロディングオプションを使用することは
推奨されません。これは、実用的な環境ではまだ安定性が確認されておらず、予期しない
結果をもたらす可能性があるためです。
日本語のマルチバイト文字に関する基本事項
多くの日本語の文字は1文字あたり複数のバイトを必要とします。加え
て、日本語の環境では複数の文字エンコーディング手法が使用されてい
ます。使用されているのは、EUC-JP、Shift_JIS(SJIS)、
ISO-2022-JP(JIS) 文字エンコーディングです。Unicodeが普及しつつあ
り、UTF-8 も使用されています。日本語環境のWebアプリケーションを
開発するためには、HTTP入出力、RDBMS、e-mailの処理においてそれぞ
れに適した文字集合を使用することが重要となります。
1文字は最大6バイトになる
マルチバイト文字は通常シングルバイト文字の2倍の幅となります。
広い幅の文字は「全角」、狭い幅の文字は「半角」と呼ばれます。
通常、「全角」文字は固定幅です。
いくつかの文字エンコーディングでは、ISO2022で定義された
マルチバイト文字列を開始/終了するためのシフト(エスケープ)シーケンスを
使用しています。
SMTP/NNTPでは、ISO-2022-JP を使用する必要があり、ヘッダとエンティティは
各RFCの規定に基づき再度符号化される必要があります。
これらは必須のものではありませんが、多くの一般的なユーザーエージェントは、
他の符号化手法を認識できないため、行っておく方が良いでしょう。
i-mode,
Vodafone live!, または
EZwebのような
携帯電話サービス用に作成されたWebページは、Shift_JISを使用する
ことになります。
リファレンス
マルチバイト文字エンコーディングと関連する問題は非常に複雑です。
ここで詳細について記述することは不可能です。詳細な事項については、
以下のURLおよび他のリソースを参照ください。
Unicode/UTF/UCS/等
&url.unicode;
日本語/韓国語/中国語文字に関する情報
&url.oreilly.cjk-inf;
&reference.mbstring.encodings;
&reference.mbstring.functions;