<

Understanding JSON in PHP and JavaScript Applications

Published on
31,061 Points
4,961 Views
11 Endorsements
Last Modified:
Introduction
JSON is an acronym for JavaScript Object Notation.  It is a text-string data transport mechanism, capable of representing simple or complex data structures in a consistent and easy-to-read manner.  Similar in concept to XML, but more efficient and more widely supported, JSON has become the dominant technology for use in AJAX applications, APIs, and other data interchange applications where data structure and data elements must be communicated between applications and web services.

JSON is frequently found in combination with RESTful APIs, where XML has rightly fallen into disuse.  This article will examine some of the ways XML and JSON are similar and different, and will show ways of using JSON to our advantage.

Some code examples will show how to create and interpret JSON strings, and detect JSON errors.

A Bit of Test Data
Since the most important thing a programmer can have is a good test case, let's start with some good test data.  Here is the information we will use for all of our code examples.  This information will represent people, giving their names and ZIP codes.  While the example is truly minimalist, it's sufficient to illustrate the principles.
firstName lastName zipCode
John      Doe      20007
Mary      Doe      20016

Open in new window


A Bit of Test Data Organization
Both XML and JSON can represent the data structure.  Here is how our data will be organized.
People (with a date attribute)
|_ Person
   |_firstName
   |_lastName
   |_zipCode

Open in new window


The Old School Way: XML
XML, or Extensible Markup Language, is a text-string data transport mechanism.  It was popularized in the 1990s when SOAP was still used for data interchange.  Today (2015) SOAP has been largely abandoned for new projects because of its difficult and arcane protocols.  Nevertheless there is a legacy of XML, so it is worth understanding what it looks like and how PHP can process an XML string.  Here is the test data, rendered in XML.  We separate the lines and indent the strings for readability, but this has no programmatic meaning.  Both XML and JSON ignore white space that is not part of the markup or data.

<?xml version="1.0" encoding="utf-8"?>
<testData>
   <people listDate="2015-11-08">
      <person>
         <firstName>John</firstName>
         <lastName>Doe</lastName>
         <zipCode>20007</zipCode>
      </person>
      <person>
         <firstName>Mary</firstName>
         <lastName>Doe</lastName>
         <zipCode>20016</zipCode>
      </person>
   </people>
</testData>

Open in new window


The first thing we can notice about the XML representation is the size of the data set.  It is 394 bytes long.  But since we can safely ignore the white space that is not part of the markup or data, we can shrink it to 282 bytes.

The second thing we can notice is the organization of the "nodes" of information.  Each person node has firstName, lastName, and zipCode.  Each person is a member of the people and people are wrapped in the testData container.

How PHP Uses XML
PHP can translate this XML string into a useful data structure, and we do not have to parse the XML ourselves -- there are built-in parsers in PHP.  Let's build a quick script to get a list all the persons with the lastName == Doe.  We will use PHP's heredoc notation to build the XML string (but we could just as easily read the XML string from a file or a web service).
Then we will create a SimpleXMLElement object and access the properties of the object to test the lastName fields for a match on "Doe."  To create the object, we call PHP's built-in function, SimpleXML_Load_String().

<?php
$xml = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<testData>
   <people listDate="2015-11-08">
      <person>
         <firstName>John</firstName>
         <lastName>Doe</lastName>
         <zipCode>20007</zipCode>
      </person>
      <person>
         <firstName>Mary</firstName>
         <lastName>Doe</lastName>
         <zipCode>20016</zipCode>
      </person>
   </people>
</testData>
EOD;

// CREATE THE OBJECT
$obj = SimpleXML_Load_String($xml);

// VISUALIZE THE OBJECT
var_dump($obj);

// GET THE DATE ATTRIBUTE FROM THE PEOPLE NODE OF THE OBJECT
echo PHP_EOL . $obj->people['listDate'];

// EXTRACT DETAILS FROM THE OBJECT
foreach ($obj->people->person as $p)
{
    if ($p->lastName == 'Doe')
    {
        echo PHP_EOL . "$p->firstName $p->lastName $p->zipCode";
    }
}

Open in new window


Here is what the SimpleXMLElement object looks like in var_dump().

object(SimpleXMLElement)#1 (1) {
  ["people"]=>
  object(SimpleXMLElement)#2 (2) {
    ["@attributes"]=>
    array(1) {
      ["listDate"]=>
      string(10) "2015-11-08"
    }
    ["person"]=>
    array(2) {
      [0]=>
      object(SimpleXMLElement)#3 (3) {
        ["firstName"]=>
        string(4) "John"
        ["lastName"]=>
        string(3) "Doe"
        ["zipCode"]=>
        string(5) "20007"
      }
      [1]=>
      object(SimpleXMLElement)#4 (3) {
        ["firstName"]=>
        string(4) "Mary"
        ["lastName"]=>
        string(3) "Doe"
        ["zipCode"]=>
        string(5) "20016"
      }
    }
  }
}

Open in new window


The New School Way: JSON
JSON, or JavaScript Object Notation, like XML, is also a text-string data transport mechanism.  It was popularized in the 2000s around the time that jQuery made AJAX applications easy and popular.  Today (2015) JSON is the tool of choice for new projects because of its elegant simplicity and easy integration into the HTTP protocol stack.  Today, almost every language has a good way of dealing with standard JSON strings.

Here is the test data, rendered in a JSON string.  Like with XML, we separate the lines and indent the strings for readability, but this has no programmatic meaning.  Both JSON and XML ignore white space that is not part of the markup or data.
{
    "people": {
        "@attributes": {
            "listDate": "2015-11-08"
        },
        "person": [
            {
                "firstName": "John",
                "lastName": "Doe",
                "zipCode": "20007"
            },
            {
                "firstName": "Mary",
                "lastName": "Doe",
                "zipCode": "20016"
            }
        ]
    }
}

Open in new window


Notice the difference in package size: 175 bytes for JSON versus 282 bytes for XML.  This is largely due to the absence of the XML closing tags required around every data element.  This is a 38% reduction in total data, representing a propellant-to-payload ratio of about 5.  In contrast, the XML representation has a ratio of 8.  Clearly JSON is much more compact and efficient, and this efficiency becomes important if we are transferring a lot of data.
 
That alone would create the compelling case to use JSON instead of XML, but there is more than storage efficiency to commend JSON, and we shall see that below when we start using it in more creative ways.

JSON Notation (the fine print)
Depending on your browser or style sheet, it may be difficult to see the difference between square brackets and curly braces.  This difference has an important meaning in JSON.  Square brackets [...] are used to encapsulate arrays.  Curly braces {...} are used to encapsulate objects.  In PHP, arrays can have either numeric or named associative keys; in JavaScript arrays have numeric keys and objects have named associative keys.  There are a few other differences, but for the most part, JSON notation renders data structures that are 100% usable in PHP.  In the JSON example above, people is an object and person is an array.

How PHP Uses JSON
PHP can translate this JSON string into a useful data structure, and we do not have to parse the JSON ourselves -- there are built-in encoders and decoders in PHP.  Let's build a quick script to get a list all the persons with the lastName == Doe.

We will use PHP's heredoc notation to build the JSON string directly into a script variable (and like XML, we could also read the JSON string from a file or a web service).  Then we will create an object and access the properties of the object to test the lastName fields for a match on "Doe."  To create the object, we call PHP's built-in function json_decode().

This encode/decode terminology may seem a little unusual at first, especially if we are used to thinking of encoded and decoded data elements in other languages or formats.  Since a JSON string is a JavaScript object, a "JSON-encoded" object is one that has been turned into a string (suitable for use in JavaScript or for data interchange), and a "JSON-decoded" object is a JSON string that has been turned back into a PHP object.

In the snippet below, take note of the way we encapsulate the @attribute that we used to acquire the listDate value.  The curly braces and quotes are required!

<?php
$jso = <<<EOD
{
    "people": {
        "@attributes": {
            "listDate": "2015-11-08"
        },
        "person": [
            {
                "firstName": "John",
                "lastName": "Doe",
                "zipCode": "20007"
            },
            {
                "firstName": "Mary",
                "lastName": "Doe",
                "zipCode": "20016"
            }
        ]
    }
}
EOD;

// CREATE THE OBJECT
$obj = json_decode($jso);

// VISUALIZE THE OBJECT
var_dump($obj);

// GET THE DATE ATTRIBUTE FROM THE PEOPLE NODE OF THE OBJECT
echo PHP_EOL . $obj->people->{'@attributes'}->listDate;

// EXTRACT DETAILS FROM THE OBJECT
foreach ($obj->people->person as $p)
{
    if ($p->lastName == 'Doe')
    {
        echo PHP_EOL . "$p->firstName $p->lastName $p->zipCode";
    }
}

Open in new window


Here is what the JSON-decoded object (an instance of PHP StdClass) looks like in var_dump().  Other than the attributes, the properties of this object are nearly identical to the properties of the SimpleXMLElement.  If we treat the properties as strings, our programming that works for XML will almost always work for JSON, too.

object(stdClass)#1 (1) {
  ["people"]=>
  object(stdClass)#2 (2) {
    ["@attributes"]=>
    object(stdClass)#3 (1) {
      ["listDate"]=>
      string(10) "2015-11-08"
    }
    ["person"]=>
    array(2) {
      [0]=>
      object(stdClass)#4 (3) {
        ["firstName"]=>
        string(4) "John"
        ["lastName"]=>
        string(3) "Doe"
        ["zipCode"]=>
        string(5) "20007"
      }
      [1]=>
      object(stdClass)#5 (3) {
        ["firstName"]=>
        string(4) "Mary"
        ["lastName"]=>
        string(3) "Doe"
        ["zipCode"]=>
        string(5) "20016"
      }
    }
  }
}

Open in new window


Converting JSON Strings into PHP Arrays Instead of StdClass Objects
Personally, I prefer the PHP object notation that uses arrows like property->property over the array notation that uses square brackets and quotes like ['property']['property'].  For me, fewer quote marks means easier typing, fewer parse errors, easier insertion into heredoc templates, etc.  But if  you prefer arrays over StdClass objects, you can turn JSON strings into arrays by setting the second argument of json_decode() to TRUE.  Then you can use PHP array notation to access the JSON data.

<?php
$jso = <<<EOD
{
    "people": {
        "@attributes": {
            "listDate": "2015-11-08"
        },
        "person": [
            {
                "firstName": "John",
                "lastName": "Doe",
                "zipCode": "20007"
            },
            {
                "firstName": "Mary",
                "lastName": "Doe",
                "zipCode": "20016"
            }
        ]
    }
}
EOD;

// CREATE THE ARRAY INSTEAD OF THE OBJECT
$arr = json_decode($jso, TRUE);

// VISUALIZE THE OBJECT
var_dump($arr);

// GET THE DATE ATTRIBUTE FROM THE PEOPLE NODE OF THE OBJECT
echo PHP_EOL . $arr['people']['@attributes']['listDate'];

// EXTRACT DETAILS FROM THE OBJECT
foreach ($arr['people']['person'] as $p)
{
    if ($p['lastName'] == 'Doe')
    {
        echo PHP_EOL . $p['firstName'] . ' ' .  $p['lastName'] . ' ' . $p['zipCode'];
    }
}

Open in new window


Converting JSON Strings Back and Forth Between Arrays and Objects
A JSON string can be converted to a PHP object, then converted back into a JSON string (possibly after we have changed some of the properties).  The same is true of a JSON string that has been converted to a PHP array.  When either of these data structures is converted back into a JSON string with json_encode() the resulting JSON strings will be valid.

<?php
$jso = <<<EOD
{
    "people": {
        "@attributes": {
            "listDate": "2015-11-08"
        },
        "person": [
            {
                "firstName": "John",
                "lastName": "Doe",
                "zipCode": "20007"
            },
            {
                "firstName": "Mary",
                "lastName": "Doe",
                "zipCode": "20016"
            }
        ]
    }
}
EOD;


// CREATE THE OBJECT AND ARRAY
$obj = json_decode($jso);
$arr = json_decode($jso, TRUE);

// RETURN THE PHP DATA TO JSON-ENCODED FORMAT
$json_obj = json_encode($obj);
$json_arr = json_encode($arr);

// COMPARE THE NEW JSON STRINGS
if ($json_obj === $json_arr) echo 'Success!'; // Success!

Open in new window


Comparing Data Types
Without the use of an XML Schema, XML has only one data type - strings.  Consider this element: <id>0</id>.  We cannot tell whether the value of id is a binary zero or a character representation of zero.  Sometimes this distinction matters, sometimes it does not (PHP is a loosely typed language).  Consider also this element: <cond>false</cond>.  Unless we build and use a separate XML schema, XML does not tell us whether this is a string containing the word "false" or a boolean value.  The default presentation is the word "false" and that may not be what we wanted.  When we add an XML schema like XSD, we can produce a much richer XML document with a fluent set of data types, but this comes at the cost of transferring and processing a great deal more information.

JSON has no need for a schema -- its data types are self-evident in the encoding.  JSON handles data in the form of "values" which can be strings, numbers, objects, arrays, boolean true or false, or null.  These values can be aggregated into more complex structures, for example, objects can contain other embedded objects or arrays.  Except for a few details about encoding, the entire JSON language definition exists in the "railroad diagrams" shown at Douglas Crockford's elegant and informative web site, JSON.org

JSON is not extensible -- there is no need to extend a language that expresses all data types.

JSON does not have alternate encodings -- it is always UTF-8, and special characters are rendered with HTML entities.

This is why JSON is readily understood to be the Fat-free Alternative to XML.

Using JSON Strings in JavaScript
It almost seems like it should not be this easy, but... JSON is a part of JavaScript!  JavaScript objects are created in clear text - exactly the same format as the JSON string shown above.  The people in our object above can be used directly by JavaScript programming.  What this means to developers is that a web service that returns JSON actually returns a clear-text string that is human-readable and also immediately useful in native JavaScript, jQuery, AngularJS, Node.JS and other JavaScript implementations of the ECMA-262 standards.

To see this in action, just plug a JSON string, verbatim, into a JavaScript program and print out the data!
<script>
var jso =
{
    "people": {
        "@attributes": {
            "listDate": "2015-11-08"
        },
        "person": [
            {
                "firstName": "John",
                "lastName": "Doe",
                "zipCode": "20007"
            },
            {
                "firstName": "Mary",
                "lastName": "Doe",
                "zipCode": "20016"
            }
        ]
    }
}
;
alert( 'Date attribute: ' + jso.people['@attributes'].listDate );
alert( 'Mary is in the "person" array at position one: ' + jso.people.person[1].lastName + ' ' + jso.people.person[1].zipCode );
</script>

Open in new window


Using JSON Strings from External Sources (eg: AJAX Requests)
The JavaScript function JSON.parse() is used to turn external JSON strings into internally useful JavaScript objects.  Here is an AJAX example that retrieves a JSON string from a server-side PHP script.  The JSON string from the server contains a representation of a single object, like this:

     {"name":"Tom","surName":"Smith","salary":"100"}
 
When this script is run, the name and salary are filled in with data from the JSON string.
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<title>AJAX/JSON Example Using jQuery</title>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>

<script>
$(document).ready(function(){
    $.get("json_object_server.php", function(jsonString){
        var jsonObject = JSON.parse(jsonString);
        $("#output p#name").html(jsonObject.name + ' ' + jsonObject.surName);
        $("#output p#salary").html(jsonObject.salary);
    });
});
</script>

</head>
<body>

<div id="output">
  <p id="name" />
  <p id="salary" />
</div>

</body>
</html>

Open in new window


Using JSON with a Database Results Set
We might want to build an application that shows information from a database.  We could tailor the server-side script to produce HTML outputs that contain the results, but if we wanted to offer client-side filtering, we would need the server-side script to be able to send its data to the browser in a convenient format.  This is where JSON shines.  

We can fetch the results set from the database and turn each row into a JSON string, something like this:
while ($row = $res->fetch_object()) echo json_encode($row);

Open in new window


With that sort of data model, the presentation layer in the client browser can include jQuery, AngularJS, or other ECMA-262 aware applications.

Advantages of JSON over PHP Serialization
A JSON string is a representation of a data structure, and it is a standalone entity.  Therefore JSON can be stored in a file, in a database, or in a PHP session.  We can retrieve the JSON string from any storage source and immediately use it in JavaScript, or turn it into a PHP object.

As such, JSON can be thought of as a serialization mechanism, capable of making data storage safe between HTTP requests.  Of course, PHP has a built-in serialize() function, but JSON is actually better.  First, JSON is a widely understood data interchange format, whereas serialized PHP data is not.  Second, PHP serialized data must be unserialized, and that is not always a certain process.  See the note here: http://php.net/manual/en/function.unserialize.php#112823
And json_encode() is faster than serialize().

Dealing with JSON_Decode() Errors
Eventually, you will need to get some JSON-encoded data into your PHP script.  And your external data source will produce something that is unusable.  You will need some form of error detection.

In the early PHP implementations of PHP's JSON functions, error detection and expression was pretty lame, returning only an integer signal of failure. Today (PHP 5.5+) it is better, with the JSON_Last_Error_Message() function.

Probably the most difficult JSON errors are the ones that arise from invalid UTF-8 characters.  PHP JSON only tells us that there was (at least) one bad character.  In very long JSON strings, this can be troublesome because we cannot readily tell where the bad character or characters are located.  A specialized script can find the bad UTF-8 characters.  Check this E-E article about Unicode and look for "Detecting JSON Errors."

Also, beware of UTF-8 encoding that adds a byte-order mark (BOM).  Windows Notepad may inject the BOM.  Your script will need to detect and strip the BOM if it is present on the front of your JSON string.

Summary
JSON has largely supplanted XML as the preferred tool for data interchange.  It is very efficient, widely understood, and works well on a variety of platforms.  If you're building an application or API today, especially a RESTful application, you should consider using JSON to your advantage.

References and Further Reading
https://en.wikipedia.org/wiki/XML
http://www.w3schools.com/xml/
http://www.w3schools.com/xml/xml_schema.asp
http://www.w3schools.com/schema/default.asp
http://php.net/manual/en/book.simplexml.php

https://en.wikipedia.org/wiki/JSON
http://www.w3schools.com/json/
http://json.org/
http://php.net/manual/en/book.json.php

Please give us your feedback!
If you found this article helpful, please click the "thumb's up" button below. Doing so lets the E-E community know what is valuable for E-E members and helps provide direction for future articles.  If you have questions or comments, please add them.  Thanks!
 
11
Comment
Author:Ray Paseur
3 Comments
 
LVL 66

Expert Comment

by:Jim Horn
Extremely well illustrated with code samples and links, and as an ETL guy this is a highly relevant topic for me as I frequently have to consume all sorts of data sources, and I'm seeing JSON much more then XML now.

Voting Yes plus recommended as Featured Article.
0
 
LVL 43

Expert Comment

by:Rob
Ray,

Great article (as always) :).  I just wanted to address the "Using JSON Strings in JavaScript" section of your article.

I'd like to see the distinction between JavaScript and jQuery/AngularJS to show that jQuery & AngularJS are frameworks of the JavaScript language. In otherwords, they are just JavaScript. They do not implement their own version of the ECMA-262 standards.  Node.js on the other hand DOES have its own version but being only a server side language, that's a different story.

On another note, JSON in the browser still needs to be decoded from a string to be a useful JavaScript native object. Any data that PHP returns in JSON format will need to be decoded using the JSON.parse() native JavaScript function.  jQuery will do this automatically when the getJSON() or ajax() with the dataType set to "json" but vanilla JavaScript will not.  For your reference: http://www.w3schools.com/js/js_json.asp

Following on from this, the example you go on to give isn't a string, but a JS object.  I'd like to see an example of using the native functions for converting JSON strings to objects as indicated here: http://www.w3schools.com/js/js_json.asp
0
 
LVL 111

Author Comment

by:Ray Paseur
Hey, Rob.  Thanks for your comments.  Why not add your clarification examples to the comment thread here, or post a new article about this?  Especially if any of my old code and data examples are overtaken by current events... technology is always advancing!
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Join & Write a Comment

The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses
Course of the Month17 days, 9 hours left to enroll

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month