PHPでFORMデータから受け取った値をjson_encodeでJSON変換するときマジッククォートでハマった話をメモしておきます。
結論としてはマジッククォートがONであればjson_encodeにFORMデータを流しこむ前にstripslashesで取り除くことに落ち着きました。
症状
とある検証ツールを作っていてJSONをSWFに流し込む仕組みを作っていたのですが、FORMデータで入力したデータがサーバーに置くとうまくいかず、XAMPPでテストしてるときはうまくいく。
具体的にはこんなコード。
$jsonData = json_decode( $_REQUEST['jsonstr'] );
これが何故か上手く通らない。なぜだ。
いろいろ追ってみたらFORMデータが勝手にエスケープされてる
いろいろ追ってたらXAMPPでは素直に出ていた値が、とあるサーバーでは勝手にエスケープされていた。
XAMPP
{ "test":"テスト" }
もちろん、XAMPPだとjson_encodeも無事動く。
とあるサーバー
{ \"test\":\"テスト\" }
json_decodeがちゃんと変換してくれない。ここだ!
原因はマジッククォート
そして、調べてみたところ、以下の記事を発見しました。
PHPスクリプト講座:マジッククォートの処理 | そふぃのphp入門
マジッククォートなんて聞きなれない言葉だと思いますが、マジッククォートという設定項目がPHPにあるというだけの事です。デフォルトでONになってるので大抵のサーバでもONになってます。php.iniのmagic_quotes_gpcという設定項目がそれにあたります。この値がONになっていると、ユーザ入力GPC(Get/Post/Cookie)からの入力に勝手に変換を行います。
Oh…まさにこれだ。サーバーのphp.ini調べたら見事にmagic_quotes_gpcがON。ちなみにXAMPPはOFF。
エスケープされててダブルクオーテーションやらなんやらがうまくjson_decodeで変換されなかった模様。うおおこれかー。
そしてリファレンスにも載ってた。
マジッククオートは、PHPスクリプトに入力されるデータを 自動的にエスケープする機能です。 コードでは、マジッククオートをオフにして 実行する際必要な時にデータをエスケープすることが望まれます。
しかも、
警告:この機能は PHP 5.3.0 で 非推奨となり、 PHP 5.4.0 で削除されました。
警告!俺に届いてないんですけど!!!
さておき回避方法
ほぼ、先程のそふぃさんの記事で触れてはいますが、先ほどのコードに修正を加えます。
if ( get_magic_quotes_gpc() ) { $jsonStr = stripslashes( $_REQUEST['jsonstr'] ); } $jsonData = json_decode( $jsonStr );
こんなかんじ。これでうまくとおりました。
おわりに
マジッククォート。小さな親切、大きなお世話な機能で大変にハマりました・・・。
もしFORMデータがうまくjson_decodeで変換されないときは、疑ってみてもいいかもしれません。
それでは、よきPHP Lifeを!