使用 json_encode 将类型提示 php8 对象转换为 json

Convert type hinted php8 objects to json using json_encode

我有以下代码。

class SomeObject implements JsonSerializable {
    public string $placeholder;
    public string $id;
    public string $model;
    public string $value;
    public bool $disabled;
    public bool $required;

    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}

class MainObject implements JsonSerializable
{
    public string $mainName;
    public SomeObject $someObject;

    public function __construct() {
        $this->mainName = (new ReflectionClass(MainObject::class))->getShortName();
        $this->someObject = new SomeObject();
    }

    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}

$main = new MainObject;
$jsonData = json_encode($main, JSON_PRETTY_PRINT);

>>> Result:
{
    "mainName": "MainObject",
    "someObject": []
}

我希望 MainObject 看起来像这样

{
    "mainName": "MainObject",
    "someObject": {
        "placeholder": "",
        "id": "",
        "model": "",
        "value": "",
        "disabled": "",
        "required": ""
    }
}

然而,json_encode() 方法似乎仅在对象具有分配给它们的值时才进行编码。如果我将 $someObject 设为关联数组,它会按预期工作。

我该怎么做?提前致谢。

来自PHP manual of get_object_vars

Uninitialized properties are considered inaccessible, and thus will not be included in the array.

因此无法继续将 get_object_vars 与未初始化的 class 成员结合使用。您要么必须:

  • 按照Alex Howansky的建议初始化变量。

  • 对 get_class_vars() 使用一些额外的技巧,这将 return 未初始化的变量。使用 array_merge 将两者结合起来将产生一个包含所需键的数组。

    public function jsonSerialize()
    {
        return array_merge(
            get_class_vars(__CLASS__),
            get_object_vars($this)
        );
    }
    

    未初始化变量的值将为空。如果需要空字符串作为回退,您可以通过应用空合并运算符的 array_map 运行 输出:

    public function jsonSerialize()
    {
        return array_map(
            fn($value) => $value ?? '',
            array_merge(
                get_class_vars(__CLASS__),
                get_object_vars($this)
            )
        );
    }
    

3v4l供参考。