Josh Schumacher: A PHP Developer

The biggest and the best in the Northwest

Josh Schumacher: A PHP Developer random header image

Standardizing a way to represent an object in PHP

April 23rd, 2008 · 2 Comments

During the process of designing our API at Treemo, one of the first major design implementation hurdles we had to overcome was how to standardize a way to define what data in an object was “exportable” and can later be transformed into XML. The solution that I came up with defines a Node and a NodeCollection object.

When deciding what the data structure should look like, I wrote some pseudo XML that we need to be able to model.

  1. <channel>
  2.         <owner name="testuser" email="test@test.com" />
  3.         <list name="foo">
  4.                 <item id="123">
  5.                         <files>
  6.                                 <image href="http://foo.bar.com" />
  7.                                 <3gp href="http://3gp.foo.bar.com" />
  8.                         </files>
  9.                 </item>
  10.         </list>
  11. </channel>

A Node has a (string) $type, (mixed) $attributes and (NodeCollection) $children. Using the above XML as a reference, our root node (let’s call it $root) would have $type = ‘channel’ and no attributes. You would then add two nodes to the NodeCollection $children, owner and list. Owner would have $attributes of array('name'=>'testuser', 'email'=>'test@test.com') and $children would be an empty NodeCollection.

The biggest design decision made about NodeCollection was that NodeCollection implements Iterator. By implementing Iterator, you can later foreach over $children and it can loop through the elements with no problem. Implementing Iterator is a pretty cool design pattern – I’ll have to write a post about it in the near future. The ability to foreach over $children helps tremendously when writing ExportNodeToXml.

Wrapping up, pseudo code to export and object to a Node that can later be transformed to XML would look like this:

  1. class Channel implements iExportable {
  2.     public function toExportable() {
  3.         $root = new Node('channel');
  4.         $root->children->addNode(new Node('list', array('name'=>'testuser', 'email'=>'test@test.com'));
  5.         $root->children->addNode(new Node('list', array('id'=>'123'));
  6.         $root->children->getNode(2)->children->addNode(new Node('files')));
  7.         $root->children->getNode(2)->children->getNode(1)->children->addNode('image', array('href'=>'http://foo.bar.com'));
  8.         $root->children->getNode(2)->children->getNode(1)->children->addNode('3gp', array('href'=>'http://3gp.foo.bar.com'));
  9.     }
  10. }

Tags: PHP · XML

2 responses so far ↓

  • 1 Matt // May 6, 2008 at 2:32 am

    Pseudo, Josh! It’s Latin.

    Anyway, annotations are the way to go to expose properties or methods to an API in an automatic way. It’s called Attribute-Oriented Programming (@OP) and it’s integrated really well into Java and .NET. Some developers go overboard with it and use it for everything… but it really is ideal for this type of thing.

    For PHP, you have to use the reflection API and parse the DocBlock. The key method is ReflectionFunction::getDocComment().

  • 2 Josh Schumacher // May 6, 2008 at 7:00 pm

    Thanks Matt, I updated my spelling for your sake. I’ve looked at reflection before and I want to have a chance to use in a project some time for sure!

    More info about php reflection can be found in the php manual – http://us.php.net/oop5.reflection

Leave a Comment