Home > Tutorials > Zend JSON - An Introduction

Zend JSON - An Introduction

Posted by dstockto on August 24, 2011

In the past few years, JSON, or JavaScript Object Notation has seemed to overtake XML and other data encoding methods on the web. It’s not as though XML isn’t used any more, but I’d venture a guess that the majority of AJAX calls made return JSON and not XML. But then again, AJAX is a much nicer acronym than AJAJ.

 I’ve also seen numerous examples of developers who create their own sort of JSON encoder rather than either using json_encode or using Zend_Json. What inevitably comes back to bite them is when the data they are encoding contains a special character like quotes, colons, curly brackets, etc. Using either json_encode or Zend_Json::encode is highly recommended over the common:

  1. echo{. $key .:. $value};

I’ve seen examples like the above so many times and it always makes me cringe.

Zend Framework contains a package called Zend_Json which was created to help PHP programmers deal with the JSON format in various ways. This tutorial will introduce you to many of the Zend_Json classes and a brief bit of functionality for each of them.

On the sidebar, you’ll find a link to a very simple Zend Framework project which demonstrates, at least to some extent, the use of all of the concepts here. Some of the examples, specifically the decoding of JSON do not demonstrate all that well in that context since JavaScript has no PHP var_dump equivalent. I encourage you to look at the code and experiment with it to see how it can work for you. I also encourage suggestions for changes or updates to make the examples more relevant or easier to follow.

Encoding

One of the first and most basic pieces of functionality provided by Zend_Json is the ability to encode PHP data as JSON. If you’re following along in the code, you can visit /json/encode to see examples of encoding for strings, objects and arrays. 

The usage of Zend_Json for encoding is very straight forward.

  1. Zend_Json::encode($data);

This will return a JSON encoded representation of whatever happens to be in $data.

For example:

  1. $data = array(
  2. 'foo' => 'bar',
  3. 12 => 'Angry Men',
  4. 3 => 'Blind Mice',
  5. );
  6.  
  7. echo Zend_Json::encode($data);
  8.  
  9. // echos {"foo":"bar","12":"Angry Men","3":"Blind Mice"}

When you’re encoding objects, you can provide a toJson method which will allow your object to define its own representation in JSON. It is worth noting though, if you are encoding an array of objects with a toJson() method or an object that contains an object with a toJson() method, it will only call the first toJson method and only if the argument is an object. At least at the time of this writing, it will not recurse through the object graph calling toJson.

Decoding

Decoding is just as straight-forward as encoding. You simply pass in the JSON encoded string and you’ll get out strings or objects. Objects in JSON format, by default, will decode as PHP arrays. The decode method does allow you to specify you’d prefer to receive objects though. In this case it will return a stdClass object.

  1. // Decode objects as PHP array
  2. $decoded = Zend_Json::decode($data);
  3.  
  4. // Decode objects and PHP stdClass objects
  5. $decoded = Zend_Json::decode($data, Zend_Json::TYPE_OBJECT);

Pretty Print

You may have noticed that while it’s certainly possible to read a JSON encoded string, sometimes the object graph can be pretty complicated. Zend_Json provides a way to format the JSON string so that it’s easier to read.

  1. $prettyString = Zend_Json::prettyPrint(
  2. $complexDataStructure
  3. );

You can specify what to indent with in a second optional parameter:

  1. $prettyString = Zend_Json::prettyPrint(
  2. $complexDataStructure, array(‘index’ => ‘ ‘)
  3. );

By detault, prettyPrint() uses a tab character.

Standard: 

{"foo":"bar","fizz":"bazz","embedded":{"inner":"stuff","outer":"things","number":1,"0":{"anotherInside":"value"}}}

Pretty Json Encoding:

{    "foo":"bar",
    "fizz":"bazz",
    "embedded":{
        "inner":"stuff",
        "outer":"things",
        "number":1,
        "0":{
            "anotherInside":"value"
       }
    }

You can play with this example in the provided sample application by going to /json/pretty-print

JSON Expressions

Zend_Json allows you to move objects between PHP and JavaScript. JavaScript objects often have functionality built-in. Using Zend_Json_Expr, you can actually create an object in PHP that contains runnable JavaScript code when it’s converted to JSON. Since by default anything enclosed in quotes in PHP will be converted to a string in the JavaScript JSON, you must indicate that the string should be considered to be a function by embedding it in the Zend_Json_Expr object.  This can be done as so:

  1. $object = array(
  2. 'standardString' => 'This is a normal string',
  3. 'method' => new Zend_Json_Expr(
  4. "function() { alert(\'Javascript function!\'); }"
  5. )
  6. );

When you pass this object into Zend_Json::encode, you must pass in an additional option that tells the encoder to look for the expressions. This will recurse through the tree and find any embedded Zend_Json_Expr objects anywhere within the object graph.

  1. echo Zend_Json::prettyPrint(Zend_Json::encode(
  2. $this->exprObject,
  3. false,
  4. array('enableJsonExprFinder' => true)
  5. ),
  6. array('indent' => ' ')
  7. );

An example of using this code is in the sample application at /json/expressions.

Converting XML to JSON

Another cool feature, although I don’t currently have a practical use for it, is the ability to convert  XML strings into JSON. This includes any attributes that may be on the elements in the XML. In any case, a simple example of this is below:

The XML:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <bookstore>
  3. <book>
  4. <author>
  5. <first_name>Frank</first_name>
  6. <middle_initial>N</middle_initial>
  7. <last_name>Beans</last_name>
  8. </author>
  9. <title>A Can, A Man and a Plan</title>
  10. <description brief="A story about a man and his
  11. beans.">
  12. This autobiography follows the story of Frank N Beans
  13. as he traveled the country on the rails eating only
  14. Pork and Beans for six years until he finally
  15. managed to find employment at a circus
  16. sideshow due to an unfortunate incident
  17. involving a zipper.
  18. </description>
  19. </book>
  20. </bookstore>

Converting XML to JSON is also very simple. You simply need to get the xml into a variable and pass it to Zend_Json::fromXml().  The method takes an optional second parameter if you wish for the JSON to also convert the attributes. If you choose to include this second parameter (by default it is set to ignore attributes), then any elements with attributes will have an @attributes part and the text part will be in @text.

  1. {
  2. "bookstore":{
  3. "book":{
  4. "author":{
  5. "first_name":"Frank",
  6. "middle_initial":"N",
  7. "last_name":"Beans"
  8. },
  9. "title":"A Can,
  10. A Man and a Plan",
  11. "description":{
  12. "@attributes":{
  13. "brief":"A story about a man and his beans."
  14. },
  15. "@text":"This autobiography follows the story of
  16. Frank N Beans as he traveled the country on the rails
  17. eating only Pork and Beans for six years until he finally
  18. managed to find employment at a circus sideshow due
  19. to an unfortunate incident involving a zipper."
  20. }
  21. }
  22. }
  23. }

You can see this example in the application at /json/xml

At this point, this “tutorial” is not so much a tutorial as just an introduction to some of the features and functionality of the Zend_Json package 

Zend_Json also provides a Zend_Json_Server class which can be used to build a JSON RPC server. I’ll create a tutorial around its functionality soon.

Thank you and I hope this was helpful,
David Stockton

Comments:

Posted by Ricardo Machado on
Hi!
That's a very good article! However you've an error. Where you say "Objects in JSON format, by default, will decode as PHP arrays." it's wrong, normally will decode as objects.

Check it here: http://pt.php.net/json_decode

Hugz and keep up the good work
Posted by dstockto on
@Ricardo: You are correct as far as json_decode. It will convert to a PHP object (stdClass). However, by default, Zend_Json::decode converts to a PHP array. You can specify the second, optional parameter to get Zend_Json::decode to decode as an object. The decode example above shows this.

Thanks for reading and for the feedback.

David
Posted by Chad on
Great article! And very timely for some things I have seen lately at work.
Posted by Maarten on
Awesome article David. Been playing around a lot with JSON these last few weeks (sometimes with, sometimes without ZF). I was a bit tempted to go the lazy way and just concatenate it all..., but in terms of time/efficiency, it's just easier to understand how json_encode works and figure out how to deal with the output in jQuery. Ha, good to read I'm not the only one.

But this package kicks ass. The fromXml is pretty cool too ;)
Posted by dstockto on
@Maarten: I am really glad you liked the article. I've found that using json_encode or Zend_Json::encode is much simpler and way less error prone than concatenating stuff together. Both of those options are so much quicker to use and then you don't have to worry about dealing with special characters later on.
Posted by Kuba on
@David jsone_decode has a second parameter which makes that it returns an associative array instead of stdClass.
Posted by Rose on
So true. Honetsy and everything recognized.
Leave a Reply



(Your email will not be publicly displayed.)

Please type the letters and numbers shown in the image.Captcha CodeClick the image to see another captcha.