« GoogleのSitemaps(サイトマッププロトコル)を作ろう | トップページ | jQueryを使ってみよう »

2006年11月29日

PHPのShift_JIS文字化け対策2

以前にSJISの文字化け対策を書いてから数ヶ月経過しましたが、対策を書いた後にある仕事で見事に文字化けにハマってしまいました。
その時に新たな?発見をしましたので、今日は文字化け対策について書かせていただきます。

前回も文字化け対策の記事を見たい方は下記のリンクをご参照ください。
PHPのShift_JIS文字化け対策1

文字コードをSJISにして

$str = "一覧表";

このようなPHPプログラムを書いてみてください。

次にプレビューをしてみると、

Parse error: parse error in /xxx/xxxx/xxxxx/xxx.php on line xx

とParseエラーになると思います。

前回の記事をご覧の方や詳しい方は原因が分かると思います。
「表示」という文字が「表\示」に文字化けするのと同じ現象で、表の後ろに「\」が付くために「"」や「'」がエスケープされているのです。
先ほどの例で具体的に説明すると、

$str = "一覧表";

がプログラムでは
$str = "[88EA][9797][955C]";

と読み込んでいますので、「5C」=「\」と判断して「"」をエスケープ処理しているのです。

対策は、非常に簡単で「表」の後ろに「\」を入れるだけです。

$str = "一覧表";


$str = "一覧表\";

Shift_JISの「\」文字化けについては、原因が分かっているので問題なく開発できると思っていたのですが、思わぬところに落とし穴がありました^^;
ちなみにPHPでは

$str = "表示";

と書いても、「\」マークは入りません。それを知っていた為、私の「思い込み」でエスケープされているとは夢にも思わなかったのです(--)
まだまだ甘いなぁ。。。

折角なので、SJISの文字化けについてもう少し触れたいと思います。
プログラマーはSJISでの開発で必ずと言っていいほど、この文字化け問題にぶつかります。
では、いつ「\」がつくのでしょうか?
私が今まで経験したのは以下の2つです。
1.入力フォームの値を受け取ったとき
2.外部ファイル(テキストやExcelファイル)を読み込んだとき
1の「入力フォームの値を受け取ったとき」にが一番多いと思います。
下記のようなスクリプトをプログラムの一番上に設置すると、入力フォームから値を受け取った際に文字化けを起こしません。

if($_SERVER['REQUEST_METHOD'] == "POST") {
  if(ini_get('magic_quotes_gpc') == "1") {
    foreach($_POST as $k => $v) {
      $_POST[$k] = stripslashes($v);
    }
  }
}
if($_SERVER['QUERY_STRING'] != "") {
  if(ini_get('magic_quotes_gpc') == "1") {
  foreach($_GET as $k => $v) {
      $_GET[$k] = stripslashes($v);
    }
  }
}

フォームからは「POST」と「GET」の2種類のデータを受け取ります。
$_SERVER['REQUEST_METHOD']を参照することにより「POST」データか「GET」データを判断できます。
1行目の
if($_SERVER['REQUEST_METHOD'] == "POST") {

は、「POST」データを受け取ったら任意の処理をします。
つまり1行目から7行目は、「POST」を受け取った際に処理を行います。

8行目の

if($_SERVER['QUERY_STRING'] != "") {

は、URLに引数がある場合に処理を行います。「GET」を受け取った際に処理を行います。
8行目を
if($_SERVER['REQUEST_METHOD'] == "GET") {

としない理由は、「POST」でフォームの値を受け取る時以外は「$_SERVER['REQUEST_METHOD'] 」は「GET」になるからです。
簡単に言うと、特別な処理がない限り「$_SERVER['REQUEST_METHOD'] == "GET"」になるのです。

2行目と9行目の

if(ini_get('magic_quotes_gpc') == "1") {

前回の記事でも紹介した通り、「magic_quotes_gpc」が「On」の場合のみに処理をします。

後は、「POST」と「GET」をforeachでアンエスケープしています。
これでフォームの値は文字化けせずにスクリプトを組むことが出来るかと思います。
私の場合は、上記のような処理をオブジェクト化して使ってます。

今日は、「Shift_JISの文字化け対策2」をご紹介させて頂きました。
少しでも役に立てば幸いです。

前回の「Shift_JISの文字化け対策1」をページへ

トラックバック

このエントリーのトラックバックURL:
http://www.s-memo.net/mt/mt-tb.cgi/23

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)