JSON, XML, RSS, CSV - it's all a ContextSwitch away!

Do you love the variety of formats that you can publish and subscribe to in this veritable golden-age of computing we're enjoying? Same here. Whether it's JSON, XML, RSS, Atom, CSV or even Excel format, there's just so much choice. The challenging thing is that though there's so much choice of format, there are also so many demands to use them - ALL. So what do you do when your boss, client, friend, family-member (whom you're the technical support person for) requests this for their blog or site?

Well, if you're like me, you've approached it in a variety of different manners. There's writing a series of procedural methods; a class that has a series of static methods; an increasingly bloated class that becomes a monster; there's the factory pattern approach, the list goes on and on ad nauseum.

On a recent project, I found myself in this situation. Originally the application only returned JSON output; however it supported a &'format&' query parameter; but ignored it if present. The need arose to optionally return RSS 1.0 output, so the question was, What to do? Well I'd heard about the ContextSwitch helper in Zend Framework and got talking to a friend and former colleague who just raved about how simple they were to implement and how much time they saved. After reading the documentation and doing a test implementation - I am now also a big advocate of them. They're just so simple!

So what is ContextSwitch? It signals to your application the output formats that can supported. By default JSON and XML are supported out of the box.

So, how do they work? In your init method, add the following:

$contextSwitch = $this->_helper->getHelper('contextSwitch');<br /> $contextSwitch->addActionContext('get', array('xml', 'json'))<br /> ->setAutoJsonSerialization(false)<br /> ->initContext();

This tells your controller that the get action supports both XML and JSON output. What it also does is not auto-serialise for output, JSON responses. Helpful if you want to massage JSON content before it's output.

In your get action (or action that suits your purpose) assign the content that you are going to render to a standard view variable similar to the below:

$this->view->myOutput = array_values($outputData);<br />

Wait, wait, we're nearly done. Now, under the scripts path for your module, create two templates:

  • get.json.phtml
  • get.xml.phtml

The reason for the name is as follows:

  • the first part is the name of the action it matches (get)
  • the second part is for the output format it matches

Now, in your template, just put in the logic that will build and output the content as you desire. An example for XML output is below:

// setup the default xml payload<br /> $simplexml = simplexml_load_string('');

// render the output if there is any.<br /> if ($this->myOutput) {<br /> foreach($this->myOutput as $result) {<br /> $objProperties = get_object_vars($result);<br /> foreach($objProperties as $propName => $propValue) {<br /> $simplexml->addChild($propName, htmlspecialchars($propValue));<br /> }<br /> }<br /> }``

// output the built xml payload<br /> echo $simplexml->asXML();

What could be simpler? Not much. Now, one thing to remember is that only XML and JSON will have the required headers automatically output. For other formats, such as CSV, RSS etc, you have to add those in manually. If you're not sure what the mimetype/content-type headers are for your format of choice, have a look at: http://www.iana.org/assignments/media-types/ to get an idea. The list below provides some of the more popular ones.

</p> <ul> <li>RSS: application/rss+xml</li> <li>RDF: application/rdf+xml</li> <li>ATOM: application/atom+xml</li> </ul> <p>

So next time you get a request for outputting your content in any number of formats, here's a very simple, structured and efficient approach to doing it that should save you countless hours and effort - assuming you're using the Zend Framework.

Till next time,


About Matthew

Matthew Setter Matthew Setter is a PHP & Zend Framework specialist. If you're in need of a custom software application, need to migrate an existing legacy application, or want to know your current application's GPA - get in touch.