/
概要 ♪このページでは、PHP で、GET/POSTメソッドによりブラウザからサーバーに 送信された日本語文字列データの文字化けを防止する対策について述べています。 HTML文書 でエンコーディング方法を指定する方法、ブラウザの対応状況、PHPの 文字エンコーディング検出関数である mb_detect_encoding() 関数 による誤検出の問題、mb_detect_encoding() 関数 の特性、について述べ、それらを踏まえて、文字化けを防止する方法を 示します。 HTML文書 でエンコーディングを指定する方法 ♪ブラウザからWebサーバーへデータを送信する場合、HTML文書 に FORMタグ を入れ ておき、GETメソッドかPOSTメソッドを使い送信します。この際に使用する文字 エンコーディングは、FORMタグ の accept-charset属性 で指定することができます。 以下のように指定します。 <FORM action="..." method="post" accept-charset="euc-jp,us-ascii"> FORMの中身... </FORM> この場合、ブラウザは、EUC-JP が US-ASCII のいずれかの文字エンコーディン グでデータを送信しなければならないことになっています (HTML4.01の仕様にお いて、若干、疑問な点があります。HTML form要素 accept-charset属性の疑問点 のページをご覧下さい)。 ブラウザの対応状況 ♪しかし、世の中には、accept-charset属性 を無視して、常に同じ文字エンコーディ ングでデータを送信したり、受け取った HTML文書 と同じエンコーディングで送信 したりするブラウザが少からず存在するようです。
(詳細には確認していません。少しケースは違いますが、accept-charsetが無い場合についての調査結果が CGIと漢字コード のページに掲載されています。) 結局、ブラウザがどのような文字エンコーディングでデータを送信してくるかは、 サーバーで受け取ったデータから判定しているケースがほとんどのようです。 mb_detect_encoding() 関数 による誤検出 ♪Webサーバーにおいて、PHPを用いて、GET/POSTメソッドでブラウザから送信され たデータの文字エンコーディングを検出するには、mb_detect_encoding() 関数 を利用しますが、この関数は、文字エンコーディングを誤検出する場合がありま す。これは、mb_detect_encoding() 関数 のバグではなく、日本語の文字エンコー ディングの規格の関係上、100%正確なエンコーディング検出が不可能な文字が存 在する為です。例えば、標準的な設定のPHPで「名前」というEUC-JPの文字列の文字エンコーディングを検出すると、UTF-8と誤検出されます。文字エンコーディング検出のテストを、 PHP mb_detect_encoding() 関数のテスト1 のページで行うことができまので、お試し下さい。 mb_detect_encoding() 関数 の特性 ♪mb_detect_encoding() 関数 は、文字エンコーディングを確定できない場合、可 能性のある文字エンコーディングの中から、定められた優先順位で文字エンコー ディングを決定します。この優先順位は、mb_detect_order() 関数 で変更するこ とができます (既定値は php.ini ファイルで指定)。また、 mb_detect-encoding() の第2引数で指定することも可能です。通常は、ASCII
誤検出される文字は、この順位に応じて変わります。標準の順位の場合、JIS X0208.1990 の6878文字中、2743文字の文字エンコーディングが正しく検出され ません。誤検出される文字の一覧は、 PHP mb_detect_encoding() 関数のテスト2 のページでご覧頂けます。 文字エンコーディング検出優先順位を変えて、誤検出文字数を調査したところ、 以下のことが分かりました。
文字化けを防止する方法 ♪以上のように、
というのが、実状です。 以上のような理由から、確実に文字エンコーディングを検出する為には、確実に 文字エンコーディングを検出可能な文字を、ブラウザからの送信データに強制的 に含めておく必要があります。従って、以下のように、hidden属性の入力フィールドをフォームの中に入れておき、確 実に文字コードエンコーディングを検出可能な文字 (列) を、value属性に指定 する、という方法が有効です。 <FORM action="..." method="post"> <INPUT type="hidden" name="encode_hint" value="あ"> FORMの中身... </FORM> 謝辞 ♪このページの情報は、PukiWikiのデバッグ過程 (PukiWikiDev:BugTrack/296) において得られました。フォームにhidden属 性データを含めておくアイデアは PukiWikiDev:ぱんだ 様から、FORMタグ の accept-charset属性 に関する情報は PukiWikiDev:reimy 様から、それぞれ、頂戴しました。 意見・コメント ♪ |