TL;DR don't call jsonSerialize()
directly, always pass the object implementing it to the json_encode
function.
JsonSerializable
is a handy PHP feature that was introduced in PHP 5.4.
It lets you define how an object should be transformed into JSON when passed to the json_encode
function.
For example, if you were to order a box of chocolate and send a preview of it to someone you offer it to,
you might want to show the content of the box but not its price.
By defining an array of properties (but the return value could be anything that could be serialized to JSON), you get to decide what information will be returned in the resulting JSON:
final class ChocolateBox implements JsonSerializable
{
private int $price;
private array $chocolates;
/* Magic code to build the box... */
public function jsonSerialize() : array
{
return [
'chocolates' => $this->chocolates,
];
}
}
So far, so good.
And then, in the client, usually a controller, I sometimes see this:
final class ChocolateBoxController
{
public function indexAction(Request $request, ChocolateBoxService $chocolateBoxService) : Response
{
$chocolateBox = $chocolateBoxService->getRandomBox();
return new Response(
json_encode($chocolateBox->jsonSerialize())
);
}
}
👆 Can you spot the problem in the code above?
We're calling json_encode
and passing it the result of the jsonSerialize
method.
That's not the idea... json_encode
actually knows about the existence of the function if the object it's being passed
implements the JsonSerializable interface.
Therefore, simply passing the object to json_encode
is enough:
json_encode($chocolateBox)
👇 gives us
{
"chocolates" => [/* delicious list of chocolates */]
}
It even works when you bury the object in another structure, such as an array:
json_encode([
'data' => $chocolateBox,
])
👇 gives us
{
"data": {
"chocolates" => [/* delicious list of chocolates */]
}
}
By implementing the interface you allow json_encode
to get what it needs out of an object.
Your work stops right after that, let json_encode
do the rest...
Originally published on quentin.delcourt.be
Top comments (0)