トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

フォームでの文字化け_PHP

フォームでの文字化け〜"あいうえお眉幅"

さて、いきなり変なタイトルをつけてみたのですが、理由は後で説明します。まず以下のPHPソースを実行してみてください。

<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=EUC-JP">
</head>

<form action="formtest.php" method="POST">
メッセージ:<input type="text" name="f_tVal" size=40 maxlength=40 /><br>
<input type="submit" value=" OK " />
</form>
<hr>

<?php
    if(isset($_POST['f_tVal'])) {
        $tVal = $_POST['f_tVal'];
        print("text = $tVal<br>\n");
    }
?>

<hr>

</body>

なんの変哲もないフォームから入力された値を表示するだけのソースです(PHPはEUCで文字コードを扱い、上記ソースもEUCで保存されています)。

フォームの入力エリアに「文字列を表示」と入れてみます。

普通に表示されています。

次に「製造」と入れてみます。

おや、化けてしまいました。短い文字列を入れるとこのように化けることがあります。これはEUCコードを使っているが為の問題なのですが、フォームで取得した文字列が「何のエンコードが分からなくなった」のが原因のようです。

「製造」をEUCコードの16進数で表示すると、

C0 BD C2 A4

となります。

ここでおもむろにShift-JISのコード範囲を書いておきます。Shift_JISの場合は2バイトで全角1文字となり、

第一バイト目 : 0x81 - 0x9F または 0xE0 - 0xFC
第二バイト目 : 0x40 - 0x7E または 0x80 - 0xFC

となるルールがあります。

先ほどの"製造"のEUCコードは第二バイトだけ見るとShift_JISの条件に当てはまってしまいますね。これだけとは限りませんが、なぜかPHPが迷って文字化けを発生させてしまうみたいです。このShift_JISのコード範囲がキーになります。

次に謎のキーワード「あいうえお眉幅」についてです。

あいうえお眉幅

では、この問題を解決するには?と考えると、「フォームからの文字列はShift_JISではない。これはEUCだ」というのを確実に教えてあげるとよい、ということになります。逆を返すと、Shift_JISには存在しないコードをあえて埋め込んでしまうと「EUCである」ということを主張できる、ということになります。

下記のソースを見てください。これは文字化け回避処理を入れたものです。

<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=EUC-JP">
</head>

<form action="formtest.php" method="POST">
<input type="hidden" name="dummy" value="あいうえお眉幅" />
メッセージ:<input type="text" name="f_tVal" size=40 maxlength=40 /><br>
<input type="submit" value=" OK " />
</form>
<hr>

<?php
    if(isset($_POST['f_tVal'])) {
        $tVal = $_POST['f_tVal'];
        print("text = $tVal<br>\n");
    }
?>

<hr>

</body>

フォームに渡す情報で、

<input type="hidden" name="dummy" value="あいうえお眉幅" />

のような隠し属性を入れています。

「あいうえお眉幅」、これがキーになります。EUCコードのこの文字列を16進数で表すと、

A4 A2 A4 A4 A4 A6 A4 A8 A4 AA C8 FD C9 FD

となります。「あいうえお」の全角それぞれの第一バイト目が「A4」となり、これはShift_JISコードに含まれていません。「眉幅」の全角それぞれの第一バイト目、第二バイト目共にShift_JISコードに含まれていないコードです。つまり、確実に「EUCである」と判定できます。

文字化け回避のため、フォームに渡す隠し属性として「あいうえお眉幅」を入れてあげる、というのはよく使われるみたいです。

この回避策はネットからの情報で知ったのですが、ほか「美乳」もいいらしいです。これを16進数で表すと

C8 FE C6 FD

となり、同じくShift_JISと誤判定しないための条件がそろってます。ただ、隠し属性で入れたとしてもHTMLソースを見ると表示されますので、無難な文字列ということで「あいうえお眉幅」で(^_^;;。「龠」(F3 FE)もよく使われるものみたいです。

HTMLのソースを眺めたときにこれらの暗号的な文字列が含まれていたら、「あぁ、文字化け対策してるんだな」と思ってみてください。しかし、ブラウザでは文字コード判別を 第一バイト目も見てチェックしないのだろうか・・・

Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.