《PHP8上級試験対策》JsonSerializableでオブジェクトのJSON表現をカスタマイズする

  • URLをコピーしました!

はじめに

JsonSerializableインターフェイスを実装すると、オブジェクトが json_encode() されたときに、どのようなJSON形式で出力されるかを自由にコントロールできます。
ただし、「json_decode()で元のクラスに戻せる」と思ってしまうのは要注意ポイントです。
本記事では、実際のコード例をもとに正しい動作を整理します。

キーワード:JsonSerializable / jsonSerialize / json_encode / json_decode / JSON変換 / クラスのシリアライズ

目次

🧩 JsonSerializableとは?

JsonSerializable は PHP に用意されているインターフェイスで、json_encode() の際に呼び出される jsonSerialize() メソッドを定義します。

interface JsonSerializable {
    public function jsonSerialize(): mixed;
}

これを実装したクラスでは、jsonSerialize() が返す値をそのまま JSON 変換対象として扱うことができます。
つまり、自分の好きな構造に変換ルールをカスタマイズできるということです。

🧪 実際のコード例

<?php
declare(strict_types=1);
error_reporting(-1);

class Hoge implements JsonSerializable {
    public function __construct(
        private int $num,
        private string $str,
    ) {}

    public function jsonSerialize(): mixed {
        return ['num' => $this->num, 'str' => $this->str];
    }
}

$obj = new Hoge(1, '2nd');
var_dump($obj);

$js = json_encode($obj);
var_dump($js);

$obj2 = json_decode($js, true);
var_dump($obj2);

📊 実行結果

object(Hoge)#1 (2) {
  ["num":"Hoge":private]=>
  int(1)
  ["str":"Hoge":private]=>
  string(3) "2nd"
}
string(21) "{"num":1,"str":"2nd"}"
array(2) {
  ["num"]=>
  int(1)
  ["str"]=>
  string(3) "2nd"
}

🧠 挙動のポイント

処理内容
$obj = new Hoge(1, '2nd');クラス Hoge のインスタンス生成
json_encode($obj)jsonSerialize() が呼ばれ、返り値の配列をJSON文字列に変換
json_decode($js, true)JSON文字列を 配列 に変換(クラス情報は失われる)

⚠️ よくある誤解ポイント

「JsonSerializableを実装すれば、json_decode()で元のクラスに戻せる」

これは 誤り です。

json_encode() は「文字列化」するだけで、クラス名などのメタ情報を持ちません。
そのため、json_decode() では単なる配列(または stdClass)として復元されます。

元のクラスに戻したい場合は、自分でコンストラクタを呼び出すなどして再構築する必要があります。

$obj3 = new Hoge($obj2['num'], $obj2['str']);

🧭 図解:処理の流れ

┌─────────────┐
│ Hoge object │
│ num=1       │
│ str='2nd'   │
└─────┬───────┘
      │ json_encode()
      ▼
┌────────────────────────┐
│ JSON文字列              │
│ {"num":1,"str":"2nd"}  │
└─────┬──────────────────┘
      │ json_decode()
      ▼
┌──────────────────────┐
│ 連想配列または         │
│ stdClassオブジェクト   │
└──────────────────────┘

✅ まとめ

項目内容正誤
JsonSerializableでjson_encodeの動作をカスタマイズできるjsonSerialize()メソッドを定義することで、オブジェクトのJSON出力を自由に制御できる✅ 正しい
jsonSerialize()で返した値がJSONになるメソッドの戻り値がそのままjson_encodeの対象となる✅ 正しい
json_decodeで元のクラスに戻せるjson_decode()では型情報が失われ、配列またはstdClassとして復元される❌ 誤り
提示コードの出力内容object → JSON文字列 → 配列の順で変換される挙動は正しい✅ 正しい

この記事が気に入ったら
いいねしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次