Using Parent Class’s jsonSerialize When Overridden By Child

Recently, I needed to pass information from a class object to a logger. The data needed to include event information from the child class as well as data from the parent. The methods were protected so json_encode wasn’t an option since it only returns publicly available content.

A workaround is to use jsonSerialize() which allows us to specify exactly what data will be used whenever json_encode is called on it. It even works on private/protected content so it’s a great fit for this situation.

Adding it to the class requires adding use JsonSerializable; before the class begins and implementing it on the class.

class Child_Class extends Parent_Class implements JsonSerializable {

After that, a public method called jsonSerialize() needs to be included. The return here will set up our data for serialization. So far so good.

The catch comes when we try to use jsonSerialize() in the parent class. It’ll be overwritten by the implementation in the child class. So how do we get around this obstacle?

One possible way is to load the parent class inside the child. We could do that this way in the child class:

public function jsonSerialize(): array {
    $to_serialize['child'] = 'child content',
    $to_serialize['parent'] = parent::jsonSerialize();

 return $to_serialize;

We can load jsonSerialize from the parent by using the scope resolution operator :: which lets us specify where we’re loading jsonSerialize. I don’t really want to load this through the child though since the logging is in the parent class.

Instead I can load it in the parent class this way:

                'prop-child' => $this,
                'prop-parent' => self::jsonSerialize(),

In this case $this refers to the jsonSerialize() in the child because it is overriding the parent. To load the parent’s implementation, we use the scope resolution operator and point it to self.

Now we have the output we were expecting whenever we use json_encode on this class.

Leave a Reply