Is there any way I can set up PHP objects so that when I try to convert them to JSON, all of their protected properties will be shown?
I have read other answers suggesting I add a toJson()
function to the object, but that may not really help me a great lot. In most cases, I have an array of objects and I perform the encode on the array itself.
$array = [
$object1, $object2, $object3, 5, 'string', $object4
];
return json_encode($array);
Yes, I can loop through this array and call toJson()
on every element that has such method, but that just doesn't seem right. Is there a way I can use magic methods to achieve this?
You can implement the JsonSerializable
interface in your classes so you have full control over how it is going to be serialized. You could also create a Trait
to prevent copy pasting the serializing method:
<?php
trait JsonSerializer {
public function jsonSerialize()
{
return get_object_vars($this);
}
}
class Foo implements \JsonSerializable
{
protected $foo = 'bar';
use JsonSerializer;
}
class Bar implements \JsonSerializable
{
protected $bar = 'baz';
use JsonSerializer;
}
$foo = new Foo;
$bar = new Bar;
var_dump(json_encode([$foo, $bar]));
Alternatively you could use reflection to do what you want:
<?php
class Foo
{
protected $foo = 'bar';
}
class Bar
{
protected $bar = 'baz';
}
$foo = new Foo;
$bar = new Bar;
class Seriailzer
{
public function serialize($toJson)
{
$data = [];
foreach ($toJson as $item) {
$data[] = $this->serializeItem($item);
}
return json_encode($data);
}
private function serializeItem($item)
{
if (!is_object($item)) {
return $item;
}
return $this->getProperties($item);
}
private function getProperties($obj)
{
$rc = new ReflectionClass($obj);
return $rc->getProperties();
}
}
$serializer = new Seriailzer();
var_dump($serializer->serialize([$foo, $bar]));