json_encode PHP对象及其受保护的属性


json_encode PHP objects with their protected properties

有没有任何方法可以设置PHP对象,以便在尝试将它们转换为JSON时,显示它们所有受保护的属性?

我读过其他建议我为对象添加toJson()函数的答案,但这可能对我没有太大帮助。在大多数情况下,我有一个对象数组,并对数组本身执行编码。

$array = [
    $object1, $object2, $object3, 5, 'string', $object4
];
return json_encode($array);

是的,我可以循环遍历这个数组,并对每个有这种方法的元素调用toJson(),但这似乎并不正确。有没有一种方法可以让我用魔法来实现这一点?

您可以在类中实现JsonSerializable接口,这样您就可以完全控制它的序列化方式。您还可以创建一个Trait来防止复制粘贴序列化方法:

<?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]));

或者,你可以使用反射来做你想做的事:

<?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]));