1

I have the following code.

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": []
}

I would like the MainObject to look like this

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

however it seems that json_encode() method will only encode if objects have values assigned to them. if I make $someObject an associative array it works as expected.

How can I do this? Thanks in advance.

2
  • 1
    Default them? public string $placeholder = ''; Commented Sep 29, 2021 at 13:55
  • Yup! that works , thank you. Is there another way to do it without setting default values? Commented Sep 29, 2021 at 15:27

1 Answer 1

1

From the PHP manual of get_object_vars:

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

So it's not possible to continue using get_object_vars in combination with the uninitialised class members. You'll either have to:

  • Initialise the variables, as proposed by Alex Howansky.

  • Use some additional trickery with get_class_vars(), which will return uninitialised variables. Using an array_merge to combine the two will result in an array with the desired keys.

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

    The values of the uninitialised variables will be null. If the empty strings as fallback are required, you can run the output through an array_map that applies the null coalescing operator:

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

3v4l for reference.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.