PHPでFORMデータから受け取った値をjson_decodeでJSON変換するときマジッククォートでハマった話

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: マジッククオート – Manual

マジッククオートは、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を!