Очень часто возникает ситуация когда необходимо сериализовать тот или иной класс в 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);
}
}