coderholic

Javascript, JSON and PHP

JSON data is commonly used as a simple way to send data back to client side javascript from the server. For example, a PHP script may output the following JSON to confirm that an action was taken:

{success: true, message: "It worked!"}

or in the case of failure:

{success: fase, message: "It didn't work!"}

Below is a basic javascript callback function to process the JSON data, displaying the returned message:

function callback(data) {
    if(data.success) alert(data.message);
    else alert('ERROR:' + data.message);
}

Sometimes it's actually useful to send back javascript code to in the JSON data, to be run on the client. For example, if an Ajax request is made that updates some account information we could return javascript code to update several parts of the page with the new information. Here's PHP code that outputs JSON data which includes javascript code:

$response = array('success' => 'true', 
    'code' => "jQuery('#id').html('Success!');");
echo json_encode($response);
// Outputs {success: true, code: "jQuery('#id').html('Success!');"}

Note how in the returned JSON data "code" is actually a string, so it won't be possible to run the code simply by doing "data.code()" on the client. Instead we must explicitly tell javascript to evaluate the string as code. Below is an example of how we can do this using eval:

function callback(data) {
    if(data.success && data.code) eval(data.code); 
}

If we wanted to update the page with HTML more complicate the the simple "Success!" message in the previous example we must be careful to escape any quotes in the HTML correctly. If we wanted to set the content to: "Javascript", "json", "PHP" then we'd need to do the following:

$response = array('success' => 'true', 
    'code' => "jQuery('#id').html('\"Javascript\", \"json\", \"PHP"');");
echo json_encode($response);

And It's easy to imagine a far more complicated example. The code becomes less readable, and if you accidentally forget to escape one of the quotes, or escape of the quotes that shouldn't be escaped, then the whole thing breaks. A nice alternative is ty store the HTML as a separate JSON property and then to reference it, avoiding the need to escape the quotes and making the code easier to read:

$response = array('success' => 'true', 
    'html' => '"Javascript", "json", "PHP"',
    'code' => "jQuery('#id').html(this.html);");
echo json_encode($response);

However, to make the "this.html" reference work the clients side callback function will need to changed, as eval() runs the code in global scope. This means that "this.html" will refer to a global html variable rather than the one in our JSON data. We can get around this problem by using the apply function as follows:

function callback(data) {
    if(data.success && data.code) {
        var f = new Function(data.code);
        f.apply(data);
    }
}

And here's a complete example which uses jQuery to perform the Ajax call:

jQuery.get('update.php', {} function(data) {
    if(data.success && data.code) {
        var f = new Function(data.code);
        f.apply(data);
    }, 'json');
Posted on 29 Mar 2009
If you enjoyed reading this post you might want to follow @coderholic on twitter or browse though the full blog archive.