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.
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.