toyModSer - a Toy Modelled SerializerAfter working on a Java project that used EMF, I've discovered the wonders of modelling. I think EMF is a bit over the top for what I need in modelling, but, it's definitely got the core bits you need. One thing that we ended up using it for was object serialization. I thought it would be useful to show how to do something similiar in PHP. What I'll be showing is a set of conventions used when defining classes which drive how the objects of that class will get serialized. In this particular case, we'll be serializing from and to JSON. The particular incarnation of code I'm going to describe here, is what I consider a toy; it's just meant to show the flavor of what you can do. A real modelling framework would handle more elaborate types that my sample here. And a real serializer built on it would serialize to more formats. Note this code requires at least PHP 5.1.0 for some of the reflection functions, PHPUnit for testing, and Zend Framework for the JSON functions. See the test cases for a complete run-through of the usage, but here's a brief synopsis. The idea is to annotate the properties in a PHP class to indicate that:
For instance, below is an annotated class definition of a book:
class Book {
/**
* @model type=string
*/
public $title;
/**
* @model type=string
*/
public $author;
/**
* @model type=integer
*/
public $yearPublished;
}
The 'annotations' are in the 'doc comments'. The contents of these comments (which start with /** and not just /*) are retained in the class definition at runtime for later introspection. Which is what my code does. The only sort of annotation the code current supports is given in the sample above. The doc comment can contain a line of the form:
@model type=foo
Where foo indicates the type of the data stored in the property. in this case, we have three properties, two of which hold a string, and the other which holds the only other type currently supported, integer. This format is very, very similiar to the way EMF lets you annotate Java interfaces in Javadoc comments. Now that we've annotated our class definition, what can we actually do? You'll want to create a ToyModSer object, which can be used to serialize and deserialize objects, using the Book class we defined above, using the following sort of code:
$serializerBook = new ToyModSer('Book');
You can then serialize an Book object (in this example, stored in the $book variable) with the new ToyModSer object you just created:
$json = $serializerBook->toJSON($book);
which might produce something like this, assuming your Book object was created with the respective values:
'{"title":"Breakfast of Champions","author":"Kurt Vonnegut","yearPublished":1973}'
To convert from JSON back into an object, you'll use some similiar code:
$bookCopy = $serializerBook->fromJSON($json);
So what's actually going on here? When you create a ToyModSer object, you pass in the class for which you want to create a serializer (by class name, the PHP convention). The ToyModSer object will be populated with information about the properties of the class in question; namely, the serializable properties and their types. When you actually perform a serialization, by calling toJSON() or fromJSON, the respective method will check get or put the properties on the object, and check the type at the same time to ensure they're the same as what you declared them to be in the annotation. There are easier ways to get this sort of serialization to happen. For instance, the Zend_JSON functions in the Zend Framework will do something pretty close to this. They won't, however, do it all. They can't check the types, because there's nothing to check against. And they won't create an object of the specified type while deserializing (using Zend_JSON::decode()) because they don't know what type to deserialize to. And of course the alternative to using some automated way of serializing your data is writing the serialization code for each type by hand. And the deserialization code, which is usually harder. So, there's some value add over existing serialization techniques, but really, once you've started modelling your data somehow, there are a lot more things you can do.
What about other languages?As long as your language of choice contains some amount of introspection over structured types, and reflectively setting/getting values from instances, you can do this sort of thing with that language. Languages that are more statically typed, like Java, can take advantage of this language feature by getting the type right from the class definition; no annotation required to get the type. It's easy to use a convention where you define your modelled data with public instance fields, and then use a marker interface to denote it's 'modelled serializability'. Or you could just use Java Beans. Or some other form of POJO. Where to go from hereAs I mentioned above, this is really a toy. Here are some of the ways the existing framework could (and in some cases should) be extended to make it more useful:
It's important to note that my use of doc comments was really just a convention. You may have other conventions which fit your environment better. Once nice thing about having it in the code itself is you're a lot less likely to forget to update it, compared to if it was in a separate file. Files
|
| Last updated on Thursday, June 26 2008 at 05:41:06 UTC. |
|
|
|
|