JSON Сериализация класса php с помощью JsonSerializable
Очень часто возникает ситуация когда необходимо сериализовать тот или иной класс в JSON представление по определенным правилам.
Например, мы можем это сделать с помощью такой конструкции.
<?php class Test { public $a = 'A'; public $b = 'B'; } $b = new Test(); echo json_encode($b); ?>
На выходе мы получим вот такой результат:
{"a":"A","b":"B"}
Но как быть, например, если у класса у нас есть приватные или продектед свойства, а при сериализации они все равно должны быть видны. Например, вот такой пример:
<?php class Test { protected $a = 'A'; protected $b; } $b = new Test(); echo json_encode($b);
На выходе мы получим просто пустой объект {}.
Для исправления этой проблемы в PHP существует интерфейс JsonSerializable, который и позволяет нам сериализовать класс по каки-то условиям. Например,
<?php class Test implements JsonSerializable { protected $a = 'A'; protected $b = true; public function jsonSerialize() { $result = array( 'value' => $this->a, 'result' => $this->b ); return $result; } } $b = new Test(); echo json_encode($b); ?>
Нам нужно лишь реализовать метод jsonSerialize. Теперь на выходе у нас будет вот такой результат:
{"value":"A","result":true}
Такую возможность я использую для своих небольших ORM классов, что бы все приватные и публичные свойства моделей могли сериазоваться. Для этого я использую еще и рефлексию.
И базовый класс модели сериализации выглядит уже вот так.
<?php namespace App\Model; class BaseJsonModel extends Base implements \JsonSerializable { public function __construct() { parent::__construct(); } public function jsonSerialize() { $reflect = new \ReflectionClass($this); $props = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED); $result = array(); foreach($props as $item) { $name = $item->getName(); $result[$name] = $this->$name; } return $result; } public function __toString() { return json_encode($this->jsonSerialize(), JSON_UNESCAPED_UNICODE); } }