PHPでクォーテーションが勝手にエスケープされてしまう時は

PHPでフォームから送信された文字列中にシングルクォーテーション( ' )やダブルクォーテーション( " )などの文字を含む時、サーバによって、バックスラッシュでエスケープされたりされなかったりします。

例えばフォームに「Let's note」とか入力してサブミットして、次の画面でその内容を表示しようとしたら、「Let\'s note」という感じでバックスラッシュ(または円記号)でエスケープされてしまうのです。

そして、その値がフォームに入ったまま送信してしまうと、「Let\\\'s note」みたいに今度はバックスラッシュ自体もエスケープされ、バックスラッシュが大増殖してしまうのです。

先日またひっかかりました…orz フォーム作るたびにハマってしまって、毎回「どうやるんだっけな」と調べてるような気がするのでメモしときます。

原因は magic_quotes_gpc = On

php.iniの設定で、magic_quotes_gpc という値が On になっている場合にエスケープされます。マジッククォートとは僕はPHPやるようになるまで聞いたことなかったんですが、シングルクォーテーション( ' )、ダブルクォーテーション( " )、バックスラッシュ( \ )、そしてNULL値を対象に、バックスラッシュで自動的にエスケープすることのようです。

magic_quotes_gpcのGPCは、GET/POST/COOKIEの略で、$_GET, $_POST, $COOKIEの値を自動エスケープ対象とするわけです。

なんで勝手にこんなことするのさ!(怒)

僕もPHP歴短いのでぜんぜん間違ってるかもですが、なんでこんなことするのかというと、とりあえずこのへんの文字をエスケープしておけば、プログラマが意識しなくてもSQLインジェクションを防げるだろう、という理由があるようです。

そのかわり、先ほどの「Let's note」のような、クォーテーションを文字として使いたい場合にいちいち stripslashes() などを使って取り除かなければいけないわけで、これが地味に面倒くさいし、忘れがち。データベースを扱う時はMySQLだったらmysqli_real_escape_string() を通したりすればいいし、ぶっちゃけ余計なお世話です。

で、一言文句言ってやろう(誰に?)と思って調べてたら、magic_quotes_gpcはPHP5.3.0で非推奨、PHP5.4.0で削除されたとのこと。ま、まあ、わかってもらえればいいんですよ、わかってもらえれば。

でも、僕が借りているレンタルサーバはまだPHP5.2で、さらに magic_quotes_gpc=On がデフォルトだったりして。さくらもだし、コアサーバーもだし。戦いは続く…

マジッククォートを無効にするには

php.iniに以下の設定を追加します。

magic_quotes_gpc = Off

php.iniが利用できない環境では、.htaccessに以下を追加します。

php_flag magic_quotes_gpc Off

php.iniも.htaccessも使えない場合は、stripslashesで個別撃破しましょう。

$str = stripslashes($_POST['hogehoge']);