Client / Server Data Retrieval With JSON


Now that you are well versed with the concepts and syntax of JSON, and you have a working example of how to use JSON for client-side API communication, let's see how we can take advantage of server-side technologies to transfer data between the client and the server.

Until recently, the world of asynchronous communication was ruled by XML. While in production successfully, XML is still an extremely bulky language, increasing data transfer overhead. Perhaps its biggest downfall, however, is that XML is commonly generated by server languages who many times do not have an XML converter, requiring manual conversion. Then, they are delivered to client languages, most notably JavaScript, who also do not have native support for XML. It would make more sense, for code simplicity and maintenance, for everyone to speak the same language.

Using PHP with JSON


Mentioned earlier, as of PHP 5.2, there is native support for encoding and decoding JSON using json_encode() and json_decode(), respectively. That means that you can now create JSON strings in PHP files, allow JavaScript to make calls to the file, have JavaScript manipulate the object and send it back to PHP, all in the same notation!

Getting Started


We are going to create a PHP file that will output JSON in the same manner as the Twitter API call. Since the PHP file will be hosted on the same domain as the HTML file, we can then make an asynchronous request to the object to load to the page.

If you stop and think about the difference between and JSON and a PHP associative array, you will notice they are extremely similar: they both represent the same data types in the same manner, and they both have a specific syntax for doing so. Therefore, to create a JSON object in PHP, you will simply create an associative array in the same manner as usual. When you are finished creating the array, you will pass the array into the json_encode() function, and it will take care of updating the syntax.

  1. <?php
  2. $myTweets = array(
  3.     "text" => "Just handed in my last project ever ".
  4.         "for my masters, all I have now is finals ".
  5.         "next week. Goodbye, school. Hello, life.",
  6.     "created_at" => "Thu May 07 21:36:12 +0000 2009"
  7. );
  8.  
  9. $myJSONTweets = json_encode($myTweets);
  10.  
  11. echo $myJSONTweets;
  12. #{"text":"Just handed in my last project ever for my masters, all I have now is finals next week. Goodbye, school. Hello, life.",
  13. #"created_at":"Thu May 07 21:36:12 +0000 2009"
  14. #}
  15. ?>


The only other data type to account for is including object in an associative array, but this is also trivial. Simply create another associative array and add it as a value to the main associative array.

  1. <?php
  2. $myTweets = array(
  3.     "text" => "Just handed in my last project ever ".
  4.         "for my masters, all I have now is finals ".
  5.         "next week. Goodbye, school. Hello, life.",
  6.     "created_at" => "Thu May 07 21:36:12 +0000 2009"
  7. );
  8.  
  9. $myTwitterUser = array("name" => "franklakatos");
  10. $myTweets['user'] = $myTwitterUser;
  11. $myJSONTweets = json_encode($myTweets);
  12.  
  13. echo $myJSONTweets;
  14. #{"text":"Just handed in my last project ever for my masters, all I have now is finals next week. Goodbye, school. Hello, life.",
  15. #"created_at":"Thu May 07 21:36:12 +0000 2009",
  16. #"user":"{"name":"franklakatos"}"
  17. #}
  18. ?>


The JavaScript Call


In similar fashion as before, we need to have JavaScript access an external file to get a JSON object. While before we embedded a script tag to avoid the limitation of same-domain access with the XMLHttpRequest object, we can now take advantage of the asynchronous call as we are hosting the PHP file.

Note: I will be using jQuery to help us out with the XMLHttpdRequest

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <title>Twitter API w\ JSON</title>
  5. <script type="text/javascript" src="http://www.google.com/jsapi"></script>
  6. <script type="text/javascript">
  7. // Load jQuery
  8. google.load("jquery", "1.3");
  9. <script type="text/javascript">
  10. $(function(){
  11.     //Get the JSON string and pass it to the cb function
  12.     $.get("twitter.php", function(data){cb(data)});
  13. })
  14.  
  15. function cb(data){
  16.     //converts the JSON string to a JavaScript object
  17.     eval("myTweets="+data);
  18.     myTweets = dataToObj;
  19.     document.write(myTweets.user.name + " says:<br/>\"" + myTweets.text + "\"");
  20. }
  21. </head>
  22. </body>
  23. </html>


Perhaps the most confusing part of all of this is the use of the eval() function. The eval function takes a string and executes it like it is code. When we receive JSON from PHP, it is simply a string that is notated as a JavaScript object, but it is not yet a JavaScript object. It is up to JavaScript to take this string and covert it to an object. That is what eval() is used for, and as you can see we assigned it to the variable name myTweets.

Going Back to the Server


So let's say you have a system in place that allows you to update the text property and PHP will update Twitter accordingly. That means we can update the object that PHP originally provided us with, update the values of some properties, and send it back to PHP.

  1. myTweets.text = "My New Text"


When you finish with updates such as the former, you can then serialize the object back into a JSON string and send it in a POST request back to PHP. There are many jquery plugins to do this, or if you prefer a little lower level, JSON.org offers a parser for the converting.

  1. //implements the JSON.org parser
  2. mySerializedTweets = JSON.stringify(myTweets);
  3. $.post("twitter.php",{page: submit, obj: mySerializedTweets});


Now, PHP can receive the JSON string and convert it back into the associative array you started with.

  1. $myTweets = json_decode($_POST['obj']);