100日後に完成するゲームシステム 28日目「phpでjsonデータを扱う時は連想配列処理に注意するという話し」

2021年2月10日

テクノロジー 特集

eyecatch PHPとJavascriptはプロ級の、弓削田です。 でも、未だに初歩的なミスもするし、知らない仕様もまだまだ存在するという事を思い知らされたので、 今回は、ゲームの内容から少し外れて、プログラミングの話をします。

PHPでJSONデータを読み込むと不具合に繋がった件

これは、ゲームのステージデータなどを、jsonデータで格納して、PHPでそのjsonファイルを読み出して、扱うという時に起きた不具合です。 phpでは、jsonデータを扱う、json_encode()とjson_decode()関数を便利に使っているんですが、まずは、サンプルプログラムを見てください。 { "a" : [1,2,3], "b" : [4,5,6] "c" : {"d":7,"e":8,"f":9}, "d" : {} } こんな感じのjsonファイルを用意して、 <?php $json = file_get_contents("sample.json"); $dec = json_decode($json , true); echo json_encode($dec); こんな風に、読み込んだjsonデータを一度オブジェクトに変換して、再度jsonエンコードしてechoするというプログラムがありました。 これをjavascriptのajaxで読み取って、JSON.parse(%json-data&);とすれば、基本階層がa,b,c,dというkey値のデータが取得できるんだけど、
aとbは、通常の数値配列、 cは、連想配列 dは、値が入っていない、連想配列・・・
のつもりで用意していたのだが、 javascriptで、dに値をセットしても、うまく取り出せない・・・ なんでだ・・・

原因判明

javascriptでパースしたデータを見てみると、次のように変換されていた。 { "a" : [1,2,3], "b" : [4,5,6] "c" : {"d":7,"e":8,"f":9}, "d" : [] } あれ??? dが配列??? なんで??? どうやらこれは、phpのjson_decode()をした際に、javascriptのobjectデータでは、{}は、連想配列(オブジェクト)としての受け皿になるが、 phpでは、array()として解釈されてしまうので、それを再びjson_encode()すると、"[]"として変換されてしまうようだ・・・ オーマイガ!!! ちなみに、javascriptで次のようなサンプルも作ってみた。 let a = {a:[],b:[],c:{}} JSON.stringify(a); > "{"a":[],"b":[],"c":{}}" う〜〜〜む・・・ javascriptでのjson変換は正常にできるのか・・・

対応方法

phpのjson_decodeをjavascript用にパーサを作るのも手間なので、とりあえず、javascriptで読み込んだ時に、"d"の型がArrayになっていた場合に、Objectに変換してあげる プログラムを書いて事なきを得た。 また、内容の無いobjectデータは、nullにして、型判定を厳密にし行うという処理をjavascript側でやるのが、一番いいだろうと判断もした。 もしかしたら、今後phpでjsonの扱いが仕様変更されるかもしれないので・・・ 思わぬトラブルに、jsonの仕様とphpの仕様が微妙に合っていないことに気がついた自分でした。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ