Tuesday, October 22, 2013

Send and receive objects using JSON, AJAX, jquery and PHP

Recently I was working on a client-side project that sent a parameter to the server via AJAX and received some data back. If you just want a string returned from the server then this is nothing new and easily done with jquery and AJAX (I think there are resouces on the web. I’ll write another tutorial soon.)
But what if you need more than a string to be returned from the server? What if the information you receive back from the server requires an object or you’d like to receive more than one parameter?
jQuery and JSON make this very easy.
First the jQuery. I’m going to use the ‘ajax’ function as you can incorporate a ‘beforeSend’ parameter. This tells your client to expect a JSON response and is necessary to prevent problems with some clients. In theory there’s no reason why you couldn’t use the simpler ‘get’ / ‘post’ or ‘getJSON’ functions but clients can be very finicky with this type of response and I’ve encountered bugs with getJSON in IE (suprise) that were very difficult to debug and were solved with the code below.
For this example I’m going to send a URL to the server and get back some information about that URL. I want two pieces of information back from the server: a boolean true / false and a string with more information regarding this result.
Let’s send a name / value pair to send to the server. You can create a JSON object or just use:
1var postData ="domain=techcrunch.com";
So I’m sending a request to the server with name ‘domain’ and value ‘techcrunch.com’ (best I could think of on short notice).
Here is the jQuery to do this:
01var postData ="domain=techcrunch.com";
02 
03 $.ajax({
04    type: "POST",
05    dataType: "json",
06    data: postData,
07    beforeSend: function(x) {
08        if(x && x.overrideMimeType) {
09            x.overrideMimeType("application/json;charset=UTF-8");
10        }
11    },
12    url: 'testURL.php',
13    success: function(data) {
14        // 'data' is a JSON object which we can access directly.
15        // Evaluate the data.success member and do something appropriate...
16        if (data.success == true){
17            $('#section1').html(data.message);
18        }
19        else{
20            $('#section2').html(data.message);
21        }
22    }
23});
Obviously we’re sending a POST request to ‘testURL.php’. Note the datatype and beforesend parameters. The ‘beforesend’ function, as mentioned before, is to deal with quirks on some clients. The interesting thing is the ‘data’ object that is returned from the server with two members: success (boolean) and message (string). You can access them directly using data.success and data.message. This is a simple example but you can of course receive just about anything in your JSON object: arrays, strings, booleans; even other objects. [edit: PHP's json_encode() does *not* work well with nested associative arrays. I've found you pretty much have to write your own JSON encoder / decoder for complex arrays].
Ok so this gets sent off to the server where we receive the ‘domain’ as a POST argument. We do our processing and want to send back the result (which needs to be in JSON format). Luckily PHP has a function which makes it very easy to do this: json_encode . Couldn’t be easier: set up an associative array and then call json_encode on it:
01// Here's the argument from the client.
02$domain = $_POST['domain'];
03 
04// Do lots of devilishly clever analysis and processing here...
05$success = processDomain($domain);
06 
07if ($success == true){
08 
09    // Set up associative array
10    $data = array('success'=> true,'message'=>'Success message: hooray!');
11 
12    // JSON encode and send back to the server
13    echo json_encode($data);
14}
15else{
16    // Set up associative array
17    $data = array('success'=> false,'message'=>'Failure message: boo!');
18 
19    // JSON encode and send back to the server
20    echo json_encode($data);
21}
That’s it! Easy! Be aware that the formatting of JSON objects can be very strict regarding single / double quotes, etc. You can read more here: json.org