Flourish PHP Unframework
This is an archived copy of the forum for reference purposes

Early implementation of JSONSerializable?

posted by mattsah 8 years ago

Per http://markmail.org/thread/ft7d6bn7swnw2dls (read the full thread) -- it seems like there is a high chance that the interface JSONSerializable will be added to PHP. This adds a single method called jsonSerialize(), which can return an alternate variable to be encoded, primarily for adding protected/private properties.

Although the interface might change, it would be an interesting concept to support this interface early. I'm not sure how keen everyone is on interfaces, but a check could be done using interface_exists(), and if not found, could add the interface. From there fJSON::encode() could check to see if an object passed implements the interface, and if so, encode the return value of it's jsonSerialize() method instead.

With regards to my previous idea of serializing XML, it might be interesting to add an XMLSerializable interface as well during that implementation, with an equivalent xmlSerialize() method.

This seems somewhat redundant only in the sense that PHP already has a serializable interface, however, this allows for more granular control, as well as supporting multiple serialization techniques.

I went ahead and implemented this on my fork cause I needed it. Although rather than include the interface in my Flourish fork I decided the implementation of the interface should be up to the developer. So basically fJSON::encode is just seeing if it's an object and if it's an instanceof JSONSerializable and if so calling the method and encoding that instead.

For me personally this is enough simply because the rest of my framework can take care of loading interfaces. It didn't seem that there was a really clean way to work the interface into Flourish itself.

posted by mattsah 8 years ago

One of the things I had overlooked when I initially implemented this is that fJSON will simply look for json_encode, and if it's available use that. I have added a new parameter $force to fJSON::encode() and fJSON::decode() in the .inK (dotink) fork on github. This parameter forces fJSON to use the manual flourish encoding and provides a good bridge for systems which have json_encode/json_decode but don't yet have the interface.

If JSONSerializable is checked for in upstream, it might be a good idea to add this parameter as well to enforce the use of it when implemented non-natively.

posted by mattsah 8 years ago

So from looking through the mailing list and PHP trunk it appears that it looks for an object that implements the JSONSerializable interface, which requires the class to have a method ->jsonSerialize(). Rather than define an interface JSONSerialize and bundle it with Flourish I think I will probably just end up looking to see if a class has the method jsonSerialize.

In the future, for things like this, please add a ticket. The only reason I ask for that is that it is easier for me to keep track of todo items when they are a ticket.

posted by wbond 8 years ago

My general suggestion would be to leave the interface availability up to the developer. I.e. don't have flourish create the interface, only have it check for it. The interface is extremely simple and generally speaking, while it essentially is equivalent to checking if the method exists, since it's the only method, it would seem to me the interface is more explicit in defining what ->jsonSerialize() does.

The possibility of conflict is low, most likely, but if someone just happened to put a method jsonSerialize() on some object, this would come up unintentionally true (and who knows the consequences), while checking for the interface is much more explicit.

The point of $force on encode() and decode() is predominately due to the lack of recursion that would be supported by json_encode($value->jsonSerialize()) -- since if there were any child objects with jsonSerialize() they would not have that method called by current stable versions of PHP, where as native support for JSONSerializable interface, would.

posted by mattsah 8 years ago