マルチバイト文字列関数 (mbstring)
導入
全ての文字をシングルバイトで一対一表現可能な言語は数多くありますが、 文字表現に単一バイトによる表現範囲を越えるほど多くの文字を必要とする言語も多くあります (1 バイトは 8 ビットから構成されます。各ビットには、1 あるいは 0 の 2 種類の値しか保持できません。そのため、単一のバイトで表すことのできる値は 256 (2 の 8 乗) 種類までとなります)。 マルチバイト文字のエンコーディング法は、 256 を越える文字を通常のビット単位の符号化システムで表現するために開発されました。
マルチバイトエンコーディングで符号化された文字列を (trim, split, splice などで) 処理する際、こうしたエンコーディングでは二つ以上の連続するバイトが 一つの文字を表す可能性があるため、特別な関数を使用する必要があります。 マルチバイトに対応しない文字列関数を文字列に適用した場合、 マルチバイト文字の先頭バイトまたは終了バイトを検出できずに文字列を壊し、 多くの場合には元の意味を失わせてしまう可能性があります。
mbstring はマルチバイト対応の文字列関数を提供し、 PHP でマルチバイトエンコーディングを処理することを容易にします。 それに加えて、mbstring は、 可能な範囲での文字エンコーディングの変換を処理します。 mbstring は UTF-8 や UCS-2 のような Unicode に基づくエンコーディングや多くのシングルバイトエンコーディングを処理するのに便利です (対応するエンコーディングを以下に示します)。
PHP の文字エンコーディングに関する要件
以下の型のエンコーディングが、PHP で安全に使用することができます。
-
シングルバイトエンコーディングで、
- 00h から 7fh の範囲の文字に関して、 ASCII 互換 (ISO646 互換) のマッピングを有する。
-
マルチバイトエンコーディングで、
- 00h から 7fh の範囲の文字では、 ASCII 互換のマッピングを有する。
- ISO2022 エスケープシーケンスを使用しない。
- 単一の文字を表す複数バイトのいずれにおいても 00h から 7fh の値を使用しない。
PHP で動作しないと思われる文字エンコーディングの例を以下に示します。
JIS, SJIS, ISO-2022-JP, BIG-5
これらのエンコーディングで書かれた PHP スクリプトは、 特に符号化された文字列がスクリプトで記述子やリテラルに使用される場合には、 動作しない可能性がありますが、入力される HTTP クエリに関して mbstring の透過的なエンコーディングフィルタを 設定することでこれらのエンコーディングをほとんど使用しないようにすることができます。
注意: SJIS, BIG5, CP936, CP949, GB18030 は、読者がパーサ/コンパイラ、 文字エンコーディングと文字エンコーディングの問題点について精通していない限り 内部エンコーディングとして使用するべきではありません。
注意: PHP でデータベースに接続する場合、性能を向上させるためにデータベースと PHP の内部エンコーディングについて同じ文字エンコーディングを使用することを推奨します。
PostgreSQL を使用している場合、 バックエンドの文字エンコーディングと異なる文字エンコーディングを使用することが可能です。 詳細については、PostgreSQL のマニュアルを参照ください。
インストール手順
mbstring は拡張モジュールです。つまり、デフォルトでは 有効にならないということです。 configure スクリプトでモジュールを有効にする必要が あります。詳細は、インストールの 節を参照してください。
mbstring モジュールに関係する設定オプションは 以下のとおりです。
-
--enable-mbstring: mbstring 関数を有効にします。このオプションは、 mbstring 関数を利用するために必要です。
mbstring 拡張モジュールを使用するためには、 libmbflライブラリが必要です。 libmbflは、mbstring 拡張モジュールにバンドルされています。システムにインストールされている libmbfl を利用する場合、 --with-libmbfl[=DIR] を指定します。
PHP 4.3.0 以降、mbstring 拡張モジュールは 日本語のほかに中国語 (簡体字)・中国語 (繁体字)・ 韓国語・ロシア語をサポートするように機能拡張されました。
PHP 4.3.4以前のバージョンの場合、 この機能を使用するには、--enable-mbstring=LANGの LANG パラメータに 以下のオプションのいずれかを追加する必要があります。 --enable-mbstring=cn を 使用した場合、簡体字中国語のエンコーディングがサポートされます。 --enable-mbstring=tw を 使用した場合、繁体字中国語のエンコーディングがサポートされます。 --enable-mbstring=kr を 使用した場合、韓国語のエンコーディングがサポートされます。 --enable-mbstring=ru を 使用した場合、ロシア語のエンコーディングがサポートされます。そして、 --enable-mbstring=ja (デフォルト)を 使用した場合、日本語のエンコーディングがサポートされます。 --enable-mbstring=all を指定した場合、サポートされるすべての文字エンコーディングが有効となります。 以前のバージョンとの互換性のため、何もオプションを指定せずに --enable-mbstring を使用した場合は 日本語のエンコーディングがサポートされます。
注意: PHP 4.3.4以降では、--enable-mbstringにより、 libmbflでサポートされている全てのエンコーディングが有効となるよう になっています。
-
--enable-mbstr-enc-trans : mbstring 変換エンジンを使用した、HTTP 入力の 文字エンコーディング変換を有効にします。この機能が有効の場合、 HTTP 入力文字エンコーディングは、自動的に mbstring.internal_encoding に変換されます。
注意: PHP 4.3.0 以降、このオプション --enable-mbstr-enc-trans は廃止され、実行時の設定 mbstring.encoding_translation に変更となります。HTTP 入力文字エンコーディング変換は、 このオプションを On に設定した場合のみ 有効となります (デフォルトは Offです)。
-
--disable-mbregex : マルチバイト対応の正規表現関数を無効にします。
実行時設定
php.ini の設定により動作が変化します。
名前 | デフォルト | 変更可能な範囲 | 変更履歴 |
---|---|---|---|
mbstring.language | "neutral" | PHP_INI_PERDIR | PHP 4.3.0 から利用可能です。 |
mbstring.detect_order | NULL | PHP_INI_ALL | PHP 4.0.6 から利用可能です。 |
mbstring.http_input | "pass" | PHP_INI_ALL | PHP 4.0.6 から利用可能です。 |
mbstring.http_output | "pass" | PHP_INI_ALL | PHP 4.0.6 から利用可能です。 |
mbstring.internal_encoding | NULL | PHP_INI_ALL | PHP 4.0.6 から利用可能です。 |
mbstring.script_encoding | NULL | PHP_INI_ALL | PHP 4.3.0 から利用可能です。 |
mbstring.substitute_character | NULL | PHP_INI_ALL | PHP 4.0.6 から利用可能です。 |
mbstring.func_overload | "0" | PHP_INI_PERDIR | PHP 4.2.0 から利用可能で、PHP <= 4.2.3 は PHP_INI_SYSTEM です。 |
mbstring.encoding_translation | "0" | PHP_INI_PERDIR | PHP 4.3.0 から利用可能です。 |
mbstring.strict_detection | "0" | PHP_INI_ALL | PHP 5.1.2 から利用可能です。 |
以下に設定ディレクティブに関する 簡単な説明を示します。
- mbstring.language string
-
mbstring で使用される言語設定(NLS)のデフォルト値。 この設定は mbstring.internal_encoding を定義するため、 php.ini の中で mbstring.internal_encoding は、 mbstring.language の後に置く必要があることに注意してください。
- mbstring.encoding_translation boolean
-
入力される HTTP クエリに関して、 文字エンコーディング検出および内部文字エンコーディングへの変換を行う 透過的な文字エンコーディングフィルタを有効にします。
- mbstring.internal_encoding string
-
内部文字エンコーディングのデフォルト値を定義します。
- mbstring.http_input string
-
HTTP 入力文字エンコーディングのデフォルト値を定義します。
- mbstring.http_output string
-
HTTP 出力文字エンコーディングのデフォルト値を定義します。
- mbstring.detect_order string
-
文字コード検出のデフォルト値を定義します。 mb_detect_order()も参照ください。
- mbstring.substitute_character string
-
無効な文字を代替する文字を定義します。
- mbstring.func_overload string
-
シングルバイト対応の関数を mbstring 関数の対応する関数でオーバーロード (置換)します。詳細は、 関数のオーバーロード を参照してください。
- mbstring.strict_detection boolean
-
厳密なエンコーディング検出を行います。
» HTML 4.01の規約 によると、Web ブラウザは、 フォームのデータを投稿する際にページで使用される文字エンコーディングと 異なるエンコーディングを使用することができます。 ブラウザで使用される文字エンコーディングを検出するには、 mb_http_input() を参照ください。
一般的に使用されるブラウザでは、 指定したHTML文書の文字エンコーディングをかなり正確に推定することができますが、 header() または設定パラメータ default_charset により、 Content-Type HTTP ヘッダで charset を設定する方がより良いでしょう。
Example#1 php.ini 設定の例
; デフォルトの言語を設定 mbstring.language = neutral; デフォルト言語を中立(UTF-8)に設定 (デフォルト) mbstring.language = English; デフォルト言語を英語に設定 mbstring.language = Japanese; デフォルト言語を日本語に設定 ;; デフォルトの内部エンコーディングを設定 ;; 注意: PHPで動作する文字エンコーディングを使用すること mbstring.internal_encoding = UTF-8 ; 内部エンコーディングを UTF-8 に設定 ;; HTTP入力エンコーディング変換を有効にする mbstring.encoding_translation = On ;; デフォルトのHTTP入力文字エンコーディングを設定 ;; 注意: スクリプトではhttp_inputの設定は変更できません。 mbstring.http_input = pass ; 変換しない。 mbstring.http_input = auto ; HTTP 入力を auto に設定 ; 「auto」は、「ASCII,JIS,UTF-8, ; EUC-JP,SJIS」に展開されます。 mbstring.http_input = SJIS ; HTTP入力をSJISに設定 mbstring.http_input = UTF-8,SJIS,EUC-JP ; 順番を指定 ;; デフォルトのHTTP出力文字エンコーディングを設定 mbstring.http_output = pass ; 変換しない mbstring.http_output = UTF-8 ; HTTP出力エンコーディングを ; UTF-8 に指定 ;; デフォルトの文字エンコーディング検出順序を設定 mbstring.detect_order = auto ; デフォルトの順番を auto に設定 mbstring.detect_order = ASCII,JIS,UTF-8,SJIS,EUC-JP ; 順番を指定 ;; 代替文字のデフォルト値を設定 mbstring.substitute_character = 12307 ; Unicode 値を指定 mbstring.substitute_character = none ; 文字を出力しない mbstring.substitute_character = long ; long の例: U+3000,JIS+7E7E
Example#2 EUC-JP ユーザ用の php.ini の設定
;; 出力バッファリングを無効にする output_buffering = Off ;; HTTP charsetヘッダを設定 default_charset = EUC-JP ;; デフォルトの言語を日本語にする mbstring.language = Japanese ;; HTTP 入力変換を有効にする mbstring.encoding_translation = On ;; HTTP 入力エンコーディング変換を auto に設定 mbstring.http_input = auto ;; HTTP 出力を EUC-JP に設定 mbstring.http_output = EUC-JP ;; 内部エンコーディングを EUC-JP に設定 mbstring.internal_encoding = EUC-JP ;; 無効な文字を出力しない mbstring.substitute_character = none
Example#3 SJIS ユーザ用の php.iniの 設定
;; 出力のバッファリングを有効に output_buffering = On ;; 出力の変換を有効にするために mb_output_handler を設定 output_handler = mb_output_handler ;; HTTPヘッダ charset を設定 default_charset = Shift_JIS ;; デフォルトの言語を日本語に設定 mbstring.language = Japanese ;; HTTP 入力変換を有効にする mbstring.encoding_translation = On ;; HTTP 入力エンコーディング変換を auto に設定 mbstring.http_input = auto ;; SJIS に変換 mbstring.http_output = SJIS ;; 内部エンコーディングを EUC-JP に設定 mbstring.internal_encoding = EUC-JP ;; 無効な文字を出力しない mbstring.substitute_character = none
リソース型
リソース型は定義されていません。
定義済み定数
以下の定数が定義されています。 この関数の拡張モジュールが PHP 組み込みでコンパイルされているか、 実行時に動的にロードされている場合のみ使用可能です。
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 で行う必要があります。
Example#4 php.ini で HTTP 入力変換を無効にする
;; HTTP 入力変換を無効にする
mbstring.http_input = pass
;; HTTP 入力変換を無効にする (PHP 4.3.0 以降)
mbstring.encoding_translation = OffPHP を Apache モジュールで使用する場合、php.ini の設定を httpd.conf により仮想ホスト単位で、または .htaccess によりディレクトリ単位で上書きすることが可能です。 詳細は、設定の節および Apache マニュアルを参照ください。
-
HTTP 出力
出力の文字エンコーディング変換を有効にする方法は複数あります。 まず php.ini、もうひとつは ob_start() で ob_start のコールバック関数として mb_output_handler() を指定するものです。
注意: PHP3-i18n のユーザにとっては、mbstring の出力変換は、PHP3-i18n とは異なっています。文字エンコーディングは、 出力のバッファリング機能を使用して変換されます。
Example#5 php.ini の設定例
;; 全ての PHP ページで出力の文字エンコーディング変換を有効にする ;; 出力バッファリングを有効にする output_buffering = On ;; mb_output_handler による出力変換を有効にする output_handler = mb_output_handler
Example#6 スクリプトの例
<?php
// このページでのみ出力の文字エンコーディング変換を有効にする
// HTTP 出力文字エンコーディングをSJISに設定する
mb_http_output('SJIS');
// 出力のバッファリングを開始し、コールバック関数として"mb_output_handler"
// を指定する
ob_start('mb_output_handler');
?>
サポートされる文字エンコーディング
現在、以下の文字エンコーディングが 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()) をサポートしています。
PHP 4.2.0 以降のマルチバイト拡張モジュール (mbstring) では、 対応するマルチバイト文字対応版の関数で既存の PHP 関数を オーバーロードする機能をサポートします。関数のオーバーロードを行うと、例えば substr() を PHP スクリプトでコールした場合に、 mb_substr() が代わりにコールされるようになります。 これにより、マルチバイト文字に対応しないアプリケーションの移植が容易となります。
関数オーバーロードを使用するには、php.ini の mbstring.func_overload ディレクティブに正の値を指定します。 これは、オーバーロードされる関数の種類を指定するビットマスクの組み合わせとなります。 mail() 関数をオーバーロードするには 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 文字は最大 6 バイトになる
- ほとんどの日本語マルチバイト文字は、シングルバイト文字の 2 倍の幅となります。これらの文字のことを、日本語では "全角 (zen-kaku)" と呼びます。これは、 "full width" という意味です。一方、幅の狭い文字のことは "半角 (han-kaku)" と呼びます。これは、 "half width" という意味です。しかしながら、 文字の見た目は、それを表示する際に使用するタイプフェイスに依存します。
- いくつかの文字エンコーディングでは、ISO-2022 で定義されたシフト (エスケープ) シーケンスを使用して、特定のコード範囲 (00h から 7fh まで) のコードマップを切り替えます。
- SMTP/NNTPでは、ISO-2022-JP を使用する必要があり、ヘッダとエンティティは 各 RFC の規定に基づき再度符号化される必要があります。 これらは必須のものではありませんが、多くの一般的なユーザーエージェントは、 他の符号化手法を認識できないため、行っておく方が良いでしょう。
- » i-mode, » Vodafone live!, または » EZweb のような携帯電話サービス用に作成された Web ページは、 Shift_JIS を使用することになります。
リファレンス
マルチバイト文字エンコーディングおよびそれに関連する問題は非常に複雑で、 このドキュメントの範囲を超えています。これらの問題に関連するより詳細な情報は、 以下の URL やその他のリソースを参照ください。
-
Unicode について
-
日本語/韓国語/中国語文字に関する情報
サポートされるエンコーディングの概要
目次
- mb_check_encoding — 文字列が、指定したエンコーディングで有効なものかどうかを調べる
- mb_convert_case — 文字列に対してケースフォルディングを行う
- mb_convert_encoding — 文字エンコーディングを変換する
- mb_convert_kana — カナを("全角かな"、"半角かな"等に)変換する
- mb_convert_variables — 変数の文字コードを変換する
- mb_decode_mimeheader — MIME ヘッダフィールドの文字列をデコードする
- mb_decode_numericentity — HTML 数値エンティティを文字にデコードする
- mb_detect_encoding — 文字エンコーディングを検出する
- mb_detect_order — 文字エンコーディング検出順序を設定あるいは取得する
- mb_encode_mimeheader — MIMEヘッダの文字列をエンコードする
- mb_encode_numericentity — 文字を HTML 数値エンティティにエンコードする
- mb_ereg_match — マルチバイト文字列が正規表現に一致するか調べる
- mb_ereg_replace — マルチバイト文字列に正規表現による置換を行う
- mb_ereg_search_getpos — 次の正規表現検索を開始する位置を取得する
- mb_ereg_search_getregs — マルチバイト文字列が正規表現に一致する部分があるか調べる
- mb_ereg_search_init — マルチバイト正規表現検索用の文字列と正規表現を設定する
- mb_ereg_search_pos — 指定したマルチバイト文字列が正規表現に一致する部分の位置と長さを返す
- mb_ereg_search_regs — 指定したマルチバイト文字列が正規表現に一致する部分を取得する
- mb_ereg_search_setpos — 次の正規表現検索を開始する位置を設定する
- mb_ereg_search — 指定したマルチバイト文字列が正規表現に一致するか調べる
- mb_ereg — マルチバイト文字列に正規表現マッチを行う
- mb_eregi_replace — マルチバイト文字列に大文字小文字を区別せずに正規表現による置換を行う
- mb_eregi — マルチバイト文字列に大文字小文字を区別しない正規表現マッチを行う
- mb_get_info — mbstring の内部設定値を取得する
- mb_http_input — HTTP 入力文字エンコーディングを検出する
- mb_http_output — HTTP 出力文字エンコーディングを設定あるいは取得する
- mb_internal_encoding — 内部文字エンコーディングを設定あるいは取得する
- mb_language — 現在の言語を設定あるいは取得する
- mb_output_handler — 出力バッファ内で文字エンコーディングを変換するコールバック関数
- mb_parse_str — GET/POST/COOKIEデータをパースし、グローバル変数を設定する
- mb_preferred_mime_name — MIME 文字設定を文字列で得る
- mb_regex_encoding — 現在の正規表現用のエンコーディングを文字列として返す
- mb_regex_set_options — マルチバイト正規表現関数のデフォルトオプションを取得または設定する
- mb_send_mail — エンコード変換を行ってメールを送信する
- mb_split — マルチバイト文字列を正規表現により分割する
- mb_strcut — 文字列の一部を得る
- mb_strimwidth — 指定した幅で文字列を丸める
- mb_stripos — 大文字小文字を区別せず、 文字列の中で指定した文字列が最初に現れる位置を探す
- mb_stristr — 大文字小文字を区別せず、 文字列の中で指定した文字列が最初に現れる位置を探す
- mb_strlen — 文字列の長さを得る
- mb_strpos — 文字列の中に指定した文字列が最初に現れる位置を見つける
- mb_strrchr — 別の文字列の中で、ある文字が最後に現れる場所を見つける
- mb_strrichr — 大文字小文字を区別せず、 別の文字列の中である文字が最後に現れる場所を探す
- mb_strripos — 大文字小文字を区別せず、 文字列の中で指定した文字列が最後に現れる位置を探す
- mb_strrpos — 文字列の中に指定した文字列が最後に現れる位置を見つける
- mb_strstr — 文字列の中で、指定した文字列が最初に現れる位置を見つける
- mb_strtolower — 文字列を小文字にする
- mb_strtoupper — 文字列を大文字にする
- mb_strwidth — 文字列の幅を返す
- mb_substitute_character — 置換文字を設定あるいは取得する
- mb_substr_count — 部分文字列の出現回数を数える
- mb_substr — 文字列の一部を得る