Ajax with JSON using PHP and DOJO

Buzzword alert! Buzzword alert! Synergisticly expedite transparent web-readiness! Buzzword alert! Buzzword alert!

Ok, now that I’ve got that out of the way…

Ajax is a web application development architecture that resembles more of a client-server architecture than traditional web development. In an Ajax application a client application is delivered to the browser consisting of HTML, CSS and JavaScript. The interactions of the client with the server send and receive data, data that the client then knows how to display to the user.

While Ajax has an ‘X’ which stands for XML in its name, Ajax really has nothing to do with XML at its core. In reality parsing XML is usually a lot more work than you need to do when you expect that a client will be a browser. Along comes JSON. JavaScript Object Notation is a structured format that corresponds to the needs of the client-side programming environment: JavaScript. JSON can be evaluated on the client into JavaScript object graphs, no parsing, no XML Sax or DOM parsing, just eval() into a JavaScript object and then call methods on it.

Ajax, as a hot technology, I was of course interested in learning more so I created a small example application that I could build and play with a bit. I thought I’d share it with everyone so they could use it as a quick-start example for trying some of these technologies.

I chose to use the DOJO Toolkit as my client-side framework because it seems to have a very broad library already built and a reasonable amount of documentation. DOJO is really engineered like a true software application. It really shows off the fact that you can write good code and good frameworks using the JavaScript language.

Show Me Some Code

Here’s an example of a simple blog application that talks to a single table to display articles.

showArticle.html

A very simple HTML skeleton that imports the CSS, DOJO and the Application written in JavaScript.







    blog.js

    The Application that is delivered to the Client.

    getArticle() is called and initiates an asynchronous call to the getArticle.php code. When the response comes back DOJO automatically calls the showArticle() function and passes the response data to it. The showArticle() function handles formatting the data by manipulating the HTML DOM of the page.


    dojo.require("dojo.event.*");
    dojo.require("dojo.io.*");
    dojo.require("dojo.date.*");
    dojo.require("dojo.lfx.*");
    function getArticle(id) {
    var idStr = "{\"id\":" + id + "}";
    request = {'action' : 'getArticle', 'data' : idStr};
    dojo.io.bind({
    url: "getArticle.php",
    handler: showArticle,
    mimetype: "text/json",
    content: request
    });
    }
    function showArticle(type, data, evt) {
    dojo.dom.removeChildren(dojo.byId('article'));
    appendArticlePart('title', data.title);
    var date = dojo.date.fromSql(data.time);
    appendArticlePart('time', dojo.date.toRelativeString(date));
    appendArticlePart('content', data.content);
    dojo.lfx.highlight(dojo.byId('article'), dojo.lfx.Color);
    }
    function appendArticlePart(id, value) {
    var element = document.createElement("div");
    element.id=id;
    element.innerHTML=value;
    dojo.byId('article').appendChild(element);
    }

    getArticle.php

    The code that lives on the server and responds to a given service request. This PHP code parses the HTTP request that the DOJO toolkit sends to the server. It parses the data from a JSON string into PHP objects, calls into the database and gets some values out. It then turns a PHP array into a JSON string to return to the web client.

    decode($data);
    $article = getArticle($jsonArray);
    print $json->encode($article);
    }
    function getArticle($node) {
    $result = null;
    $link = connect_db();
    if ($stmt = $link->prepare("select id, title, publish_time, content from articles where id=?")) {
    $stmt->bind_param("i", intval($node->id));
    $stmt->execute();
    $stmt->bind_result($id, $title, $time, $content);
    if ($stmt->fetch()) {
    $result = array(
    "id"=> $id,
    "title" => $title,
    "time" => $time,
    "content" => $content,
    "objectId"=> "article"
    );
    }
    $stmt->close();
    }
    $link->close();
    return $result;
    }
    function connect_db() {
    $mysqli = new mysqli("localhost", "root", null, "blog");
    /* check connection */
    if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
    }
    return $mysqli;
    }
    ?>

    While this example is written in PHP, there is nothing that would prevent you from writing the server component in any language. There are JSON libraries for every language you’ve ever heard of (and a lot that you’ve never even heard of). The notation itself is fairly simple (it’s about 700 lines of code in PHP), so implementing it in another language should be relatively easy as well.

    Consider using implementation neutral URIs for your service calls and then using something like Apache mod-rewrite to map those URIs to the proper calls in whatever language you use to implement the server code. Doing this and you should be able to completely decouple your web client from the server components.

    Resources

    Ajax
    JSON
    PHP
    DOJO Toolkit
    JSON-PHP
    PHP-JSON
    Dojo: The Definitive Guide
    Mastering Dojo: JavaScript and Ajax Tools for Great Web Experiences (Pragmatic Programmers)

    Javascript 1.7 in Firefox 2.0

    Brennan posted a blog entry about the Firefox 2.0 beta release a couple of days ago that talks about a lot of the new features in the next Firefox release. This version seems to be an evolutionary release and not a revolutionary one. A lot of work has gone on in the internals of the code, and there are quite a few new developer fatures in this release, but there are still some really cool user centric features as well. Brennan talks a lot about the user features, so check them out. For more info, also look at the new features for end users that Mozilla provides.

    I really want to look at some of the new features of Javascript though.

    Javascript 1.7

    Javascript is a great language that people often dislike for a variety of reasons. The main two reasons I’ve run across is:

    1. Lack of understanding the features of the Javascript language
    2. Frustration with incompatible DOM implementations in browsers

    The incompatible DOMs is not really Javascript’s fault of course, but it’s where a lot of the complexity comes in when you are writing client-side Javascript code. So I definitely understand that frustration. But Javascript itself is great (IMHO).

    Javascript 1.7 is picking up a lot of new features that more popular scripting langauges have such as Ruby and Python. I’ve drawn comparison to Javascript and Ruby before and a number of the new features in Javascript 1.7 only give them more feature parity.

    Generators

    Javascript 1.7 adds a yield keyword. Yield allows you leave a method of code and have the state of the method saved at that point. When the method is called again, the last state of the code is resumed (or continued) from the state of the last time the method was called. This is often used for Iterators (another new feature). It can also be used to implement things like Continuations which can be used to create state machines and parsers.

    function countdown() {
    yield 3;
    yield 2;
    yield 1;
    }

    Iterators

    Building the the new Generator functionality, Javascript 1.7 is adding an Iterator object. While previous versions of Javascript have allowed you to iterate over Array’s and the like using for...each, the Iterator allows you to build your own Iterator to iterate over any object that you create.

    Array comprehensions

    Array comprehensions allow you to intialize an array taking advantage of the Generator code. You can iterate over a collection of items inline to the Array definition to populate the Array values.

    var myArray = [ "Cool " + i for (i in range(0, 10))];

    function names() {
    yield "Geoff";
    yield "Bob";
    yield "Sue";
    }
    var nameArray = [ n + " is a name" for (n in names())];

    Multiple Return Values

    A method can return multiple values and have those values assigned to individual variables. This is an interesting feature found in Python. While you can always create a wrapper object to return the values, or use a construct like an Array, sometimes it is really handy to be able to just return multiple things from a method. No out parameters needed.

    var first, last;
    [first, last] = ["Geoff", "Lane"]
    document.write (first + " " + last + "
    \n");


    function getPersonInfo() {
    return ["Geoff", 29];
    }
    var name, age;
    [name, age] = getPersonInfo();

    let for Explicit Scoping

    let allows you to define an explicit scope of a variable. Just like var makes a variable so that it is not globally scoped, let narrows the scope to a defined block. This allows you to redefine the value of a var (or another let) variable to a more limited section of code, temporarily changing the value without effecting the value outside of that defined block.

    var x = 1;
    for (let x=0; x < 3; x++) { document.write("Value: " + x); } document.write("Value: " + x);

    Lots of fun new features plucked from the best scripting and programming languages out there. The future looks bright for web client-side development. (Of course IE won't support this stuff for 10 years probably.)