Do more, be better

Getting the hint

by John on 7 February 2011, filed under Wired in

The majority of our back-end development has been performed using PHP 5.3, which is a big step up from previous versions of PHP in terms of what the language now offers. However, sometimes despite all the work that the developers put in, there are things that don’t quite work the way you want them to. At the guts of the Luumin API is a JSON-RPC mechanism that lets the front end communicate with the core application. PHP has built in JSON encoding, which is written in C and is very fast, however it is a little simplistic in that if you give it an object it turns all of the public properties of that object into a JSON object and 99% of the time this is exactly what you want.

Sometimes, however, this is not what you want. You may want to hide fields or expose the object as something else. Say for example a date object is easier to work with in a formatted string as the system you are communicating with may not have any conceptual knowledge of what a PHP DateTime object actually is. There are a few ways around this. You could create a proxy object that will get encoded just the way you want (this tends to involve extra layers of complexity and gets tricky with complex object graphs) or you can tell the encoder how you would like it to convert your object, this can be thought of as type of class hinting.

The simplistic JSON encoder bundled with PHP can’t take hints as to how to encode classes, so if I wanted to use class hinting I would either have to resort to writing a new JSON encoder or change the way PHP works. You don’t want to write code that needs to be fast and is called frequently in native PHP as it is not going to be anywhere near as fast as the bundled one written in C and writing a parser from scratch in can be tricky to get right. More importantly why would you attempt re-invent the wheel and write your own parser when when other people have already done this?

In the end I decided to make the built-in PHP one do what I wanted it to do. I downloaded the PHP source code, found that the built-in JSON encoder and was very easily able to modify it to take a hint. This way we are able to maintain the super fast PHP JSON encoder and it’s default behavior, and we avoided having to write our own parser – and the end result is we got the desired functionality. The ability to do this is one of the great things about open source software.

First I created an interface that I have called JSONSerialisable that defines a new method called __toJsonString that returns the JSON representation of the object that you define. The built in encoder was then modified to check and see if an object implements the JSONSerialisable interface and if it does call the __toJsonString method. To ensure that the encoder still functions normally this functionality defaults to being off and is only called when a configuration flag is specified in the arguments to the php json_encode function.

Keeping in spirit with the open source nature of PHP these changes are available to download here.

Tags: ,

Something you want to say?

If you'd like to drop us a line about this blog post - or about anything at all - fill in the form below. This isn't a public comments board, so all correspondence will remain private (unless we both agree otherwise!)