Responding to an Ajax Request






Responding to an Ajax Request

Problem

You're using JavaScript to make in-page requests with XMLHTTPRequest and need to send data in reply to one of those requests.

Solution

Set an appropriate Content-Type header and then emit properly formatted data. Figure sends a small XML document as a response.

Sending an XML response

<?php header('Content-Type: text/xml'); ?>
<menu>
 <dish type="appetizer">Chicken Soup</dish>
 <dish type="main course">Fried Monkey Brains</dish>
</menu>

Figure uses the PEAR Services_JSON package to send a JSON response.

Sending a JSON response

<?php
require_once 'Services/JSON.php';
$menu = array();
$menu[] = array('type' => 'appetizer',
                'dish' => 'Chicken Soup');
$menu[] = array('type' => 'main course',
                'dish' => 'Fried Monkey Brains');
header('Content-Type: application/json');
$json = new Services_JSON();
print $json->encode($menu);
?>

Figure uses the PECL json extension (which is bundled with PHP 5.2 and later) to send a JSON response.

Sending a JSON response with PECL json

<?php
$menu = array();
$menu[] = array('type' => 'appetizer',
                'dish' => 'Chicken Soup');
$menu[] = array('type' => 'main course,'
                'dish' => 'Fried Monkey Brains');
header('Content-Type: application/json');
print json_encode($menu);
?>

Discussion

From a purely PHP perspective, sending a response to an XMLHTTPRequest-based request is no different than any other response. You send any necessary headers and then spit out some text. What's different, however, is what those headers are and, usually, what the text looks like.

JSON is a particularly useful format for these sorts of responses, because it's super easy to deal with the JSON-formatted data from within JavaScript. The output from Figure looks like this:

[{"type":"appetizer","dish":"Chicken Soup"},
{"type":"main course","dish":"Fried Monkey Brains"}]

This encodes a two-element JavaScript array of hashes. The PEAR Services_JSON module is an easy way to turn PHP data structures (scalars, arrays, and objects) into JSON strings and vice versa. Since it's a PEAR module, you can use it even if you don't have access to your php.ini file or can't install binary extensions. If you can install your own extensions, consider using the PECL json extension instead for a big speed boost. Its json_encode( ) and json_decode( ) functions turn PHP data structures to JSON strings and back again.

With these types of responses, it's also important to pay attention to caching. Different browsers have a creative variety of caching strategies when it comes to requests made from within JavaScript. If your responses are sending dynamic data (which they usually are), then you probably don't want them to be cached. The two tools in your anti-caching toolbox are headers and URL poisoning. Figure shows the full complement of anti-caching headers you can issue from PHP to prevent a browser from caching a response.

Anti-caching headers

<?php
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
// Add some IE-specific options
header("Cache-Control: post-check=0, pre-check=0", false);
// For HTTP/1.0
header("Pragma: no-cache");
?>

The other anti-caching tool, URL poisoning, requires cooperation from the JavaScript that is making the request. It adds a name/value pair to the query string of each request it makes using an arbitrary value. This makes the request URL different each time the request is made, preventing any misbehaving caches from getting in the way. The JavaScript Math.random( ) function is useful for generating these values.

See Also

Documentation on on header( ) at http://www.php.net/header. Read more about XMLHTTPRequest at http://en.wikipedia.org/wiki/XMLHttpRequest, JSON at http://www.json.org, Services_JSON at http://pear.php.net/pepr/pepr-proposal-show.php?id=198, and the PECL json extension at http://pecl.php.net/package/json. Michael Radwin's "HTTP Caching and Cache-Busting for Content Publishers" (http://public.yahoo.com/~radwin/talks/http-caching-apachecon2005.htm) is a good introduction to HTTP caching. Section 13 of RFC 2616 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13) has the gory details on HTTP caching.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows