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?


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 nausea.

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');
$contextSwitch
    ->addActionContext('get', ['xml', 'json'])
    ->setAutoJsonSerialization(false)
    ->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);

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
$simplexml = simplexml_load_string('');

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

// output the built xml payload
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.

  • RSS: application/rss+xml
  • RDF: application/rdf+xml
  • ATOM: application/atom+xml

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.


You might also be interested in these tutorials too...

Tue, Oct 5, 2010

How to Write a Secure RESTful Service in Zend Framework

So you’re up with the RESTful buzz but you’re concerned about security; as you should be! So what do you do? Well, like all good OOP practitioners, you don’t reinvent the wheel. As Steve Jobs said, “Good artists create, Great artists Steal”, or borrow in our case. So let’s look at the Amazon S3 model and implement that with our framework of choice - Zend Framework to protect your RESTful services.

Thu, Nov 25, 2010

Writing a Secure, RESTful Service in Zend Framework (Part 2)

In this article, a follow up to writing a secure, Restful service with the Zend Framework, I’m going to cover the HTTP status codes that you should use, where and when. The reason for this is that they’re a fundamental aspect of the interaction with the service. You get this right and you will make it so much better for clients to use your service; you get it wrong and you may only have a few users and they may do a lot of work for very little gain.

Sun, Nov 7, 2010

Writing a Simple Blog With Zend Framework and MongoDB

I’ve been using mongoDB and Zend Framework to make a simple, replicatable filesystem. As it went well, I thought that I could quickly apply what I’d done to create an ultra-simple blog system. Read on to find out all about it.


Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus