"BOKU"のITな日常

BOKUが勉強したり、考えたことを頭の整理を兼ねてまとめてます。

PHPでネストした複雑なJSONデータをデコードして値を取得する

f:id:arakan_no_boku:20220313003131p:plain

目次

PHPでネストした複雑なJSONデータをデコードして値を取得する

JSONフォーマットでデータを受け取る処理を書く機会が増えてます。

単純なものなら簡単です。

でも、複雑なフォーマットだと、少々迷います。

今回は、少し複雑なJSONフォーマットのデコードをサンプル的にやってみます。

複雑なJSONデータの例

例として、こういう条件のJSONデータを作ってみました。

  • Sampleの下にFrontとSecondの2つをネストしている
  • FrontとSecondで違うレイアウトのデータがはいっている
  • Secondに含まれる「Value」の中に、ダブルコーテーションがエスケープされた別のJSONフォーマットデータが含まれている
  • Frontのブロックはで囲まない「非配列」
  • Secondのブロックはで囲まれた「配列」

こんな感じになります。

$json_data = '{
        "Sample": [
          {
            "Front": {
              "ID": "XXXXXXXXXX",
              "From": "2022-03-18",
              "To": "2022-03-29",
              "Extension": "日本語",
              "NoDout": false,
              "Accept": 99990,
              "Cursor": null
            },
            "Second": [
              {
                "Time": "2022/03/14 09:40:13",
                "Value": "{\"date\":\"2022-03-14\",
                           \"emp_id\":\"I0282\",
                           \"header\":\"Base64head\",
                           \"bodydata\":\"Base64Datablock\",
                           \"count\":8}",
                "No": 1
              }
            ]
          }
        ],
        "Error": null
      }';

 

1段階目のデコード

$json_dataをデコードします。

$json_dataは、第二引数の指定で戻り値を連想配列にするか、オブジェクトにするかを選べますが、僕は「連想配列」で常にやってます。

$map = json_decode($json_data,true);

このデコードしたmapから値を取得します。

 

1段階目のデコード:Frontブロックの値を取得

Frontのほうはシンプルです。

例えば、「Front」に含まれる「Extension」の値を取得して表示するなら。

print($map["Sample"][0]["Front"]["Extension"]);

です。

これで「日本語」と表示されます。

大元のSample以下が配列なので[0]がはいってますが、まあ、普通なので、ここは悩む必要はありません。

1段階目のデコード:Secondブロックの値を取得

こちらも「Value」以外は普通に取得できます。

例えば、「time」をとるなら。

 print($map["Sample"][0]["Second"][0]["Time"]);

です。

Secondブロックは配列なので、["Second"][0]となっている部分が違うだけです。

ValueにはいっていたデータはエスケープされたJSONフォーマットなのですが、一段階目のデコードでは、配列等に変換されません。

Valueの中でダブルコーテーションがエスケープされておさめられていたJSONデータはエスケープがとれたJSONフォーマットに戻されるだけです。

 

2回目のデコード

一回目のデコードで取得したValueの中身はこうなってます。

{"date":"2022-03-14","emp_id":"I0282","header":"Base64head","bodydata":"Base64Datablock","count":8}

なので、その中の値をえるには、もう一回デコードしてやる必要があります。

2回デコードして、「emp_id」の値を取得してみます。

$map = json_decode($json_data,true);
$map2 = json_decode($map["Sample"][0]["Second"][0]["Value"],true);
print($map2["emp_id"]);

これで「I0282」と表示することができます。

 

ネタとしては、今回はこれだけです。

JSONの中にエスケープしたJSONをさらに仕込む・・というやり方は、渡す側のバリエーションとしても便利なので、これから増えるかもしれないなと思い、備忘的にやってみました。

ではでは。