Before I jump into today’s topic, there’s a bit of admin and introduction I need to do to start up the new series. See you after the jump!
All the code examples I use in this series will be released under the Modified BSD Licence (unless I mention otherwise), meaning that you’re free to take the code examples, modify them and/or use them in your application, whether open or closed source, provided you mention me (there are a couple of other minor things too). Of course if you get inspired by my code and write something equivalent that does the same job, you can do what you want with it, it’s yours. For reference, you can read the whole licence here.
Unlike Beginner’s Linux, this series will expect you to be familiar with (X)HTML and to have some basic skills with PHP and some JavaScript knowledge. I won’t start with too difficult things and as this series evolves we’ll probably see some introductions and other groundwork.
This tutorial, however, throws you in at the level of building your first ever Ajax application in PHP. So for this one, you need a working knowledge of PHP and a good grasp of programming basics.
Ajax – isn’t that some kind of cleaner?
No, not that Ajax. Ajax, or Asynchronous JavaScript and XML, is a new web technology that allows you, basically, to utilise JavaScript to get data from a server without reloading the whole webpage. This comes in handy for many things and is powering all of the new ‘rich web applications’ that are popping up now (Google Maps, Y!Mail Beta, Writely/Zoho Writer).
Basically Ajax means you can have elements of the page dynamically loaded without a page reload (asynchronously to the reloading), meaning you can update elements of the page without receiving the whole page again and without affecting the rest of the page. The XML part comes in when you get data from the server in XML format, then use JavaScript to parse that XML and do something useful with it.
Ajax works with any server-side technology, including PHP, Perl, ASP(.NET), Python, Ruby, ColdFusion, SSI, JSP… you get the idea, anything. We’ll of course be using PHP.
Right, so how do I start?
For this demo, we’re going to keep it simple and have two files. index.php is our main file that is loaded in the normal way by the user, and ajax.php is the script that JavaScript will call and will deliver some information.
So what are we actually going to do? Well, let’s break it down:
- index.php will contain a form where the user can enter their name.
- When submitted, the form will talk to ajax.php and determine whether that name is in a predefined list.
- If it is, we will say ‘Welcome back’. If not, we will say ‘Nice to meet you, stranger!’.
Building the form
This is textbook stuff here, we’ll just build a form with one textbox and one submit button (we’ll add the JavaScript later).
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>First ever Ajax application with PHP</title>
- </head>
- <body>
- <form name="ajaxform" method="get" action="#"><!-- leaving the action to do nothing for now -->
- Name: <input type="text" name="name" value="" /><br /><br />
- <input type="submit" value=" OK " />
- </form>
- </body>
- </html>
OK, so now we have our basic form, let’s build ajax.php, which will check for the name they entered in a list of names. We won’t do any fancy XML for now, we’ll simply return 1 if the name is in the list and 0 if it isn’t.
- <?php
- // Part of a tutorial by Peter Upfold
- // Released under the Modified BSD Licence:
- // http://www.opensource.org/licenses/bsd-license.php
- session_start(); // start a session
- header("Content-type: text/plain");
- // this is only plain text, so set the HTTP header accordingly
- $names = array( // this is our array of names - feel free to change/add as required!
- 'Bob',
- 'Jim',
- 'Mark',
- 'Graham'
- );
- if (in_array($_GET['name'], $names)) { // if that name is in our array above
- echo '1'; // echo 1 (tells JavaScript we know this person)
- }
- else { // otherwise
- echo '0'; // echo 0
- }
- ?>
Now try it with something random, to test the 0. Navigate to http://localhost/wherever/you/put/it/ajax.php?name=sdnjshduhwhwed and you should receive a 0. Good!
JavaScript time!
Now we need to write the JavaScript that will run this request when the user clicks the button and will interpret the 1 or 0 response to display a particular message.
Just a word of warning – Ajax is cool and everything, but do not presume all of your users have access to JavaScript and are willing to run it in their browser. In a real environment, we’d also build a fallback that doesn’t require JavaScript for users with it turned off and for people with special accessibility needs (such as those with screen readers). Don’t lock people out of your application by not providing fallback functionality.
In order to gain access to Ajax functionality, we need to initialise it in the user’s browser. There are two ways of doing this. For most (good) browsers, we use a built-in thing called XMLHttpRequest and for Internet Explorer 6/5.5 and below, we need to create an ActiveX control which does the same thing.
Once we’ve enabled this, we then send the request off to ajax.php and wait for a response. This Ajax object we’ve created has something called readyState attached to it. I won’t go through all the possibilities, but once the readyState is 4, we’re ready to rock.
So we build a little function which is run every time the readyState changes. That checks whether it’s 4 yet or not. If it is, we do the relevant processing with the information. If not, we don’t do anything and wait until the readyState changes again.
OK, so here is a basic shell of the JavaScript we will add in a minute to index.php (in fact it could be index.html, as it doesn’t have any PHP in it!). Plonk this in a <script> tag in the head of your page.
If this all looks a bit scary (maybe you haven’t done much JavaScript before), the vital thing is do not panic and don’t give up yet. For now, if you’re not confident, simply copy my code exactly and as you begin to explore it, you will be able to edit it to your needs.
- var ajaxObject = false;
- // this is our object which gives us access
- // to Ajax functionality
- function doAjaxQuery(url) {
- ajaxObject = false;
- if (window.XMLHttpRequest) { // if we're on Gecko (Firefox etc.), KHTML/WebKit (Safari/Konqueror) and IE7
- ajaxObject = new XMLHttpRequest(); // create our new Ajax object
- if (ajaxObject.overrideMimeType) { // older Mozilla-based browsers need some extra help
- ajaxObject.overrideMimeType('text/xml');
- }
- }
- else if (window.ActiveXObject) { // and now for IE6
- try {// IE6 has two methods of calling the object, typical!
- ajaxObject = new ActiveXObject("Msxml2.XMLHTTP");
- // create the ActiveX control
- } catch (e) { // catch the error if creation fails
- try { // try something else
- ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
- // create the ActiveX control (using older XML library)
- } catch (e) {} // catch the error if creation fails
- }
- }
- if (!ajaxObject) { // if the object doesn't work
- // for some reason it hasn't worked, so show an error
- alert('Sorry, your browser seems to not support this functionality.');
- return false; // exit out of this function
- }
- ajaxObject.onreadystatechange = ajaxResponse; // when the ready state changes, run this function
- // DO NOT ADD THE () AT THE END, NO PARAMETERS ALLOWED!
- ajaxObject.open('GET', url, true); // open the query to the server
- ajaxObject.send(null); // close the query
- // and now we wait until the readystate changes, at which point
- // ajaxResponse(); is executed
- return true;
- } // end function doAjaxQuery
- function ajaxResponse() { // this function will handle the processing
- // N.B. - in making your own functions like this, please note
- // that you cannot have ANY PARAMETERS for this type of function!!
- if (ajaxObject.readyState == 4) { // if ready state is 4 (the page is finished loading)
- if (ajaxObject.status == 200) { // if the status code is 200 (everything's OK)
- // here is where we will do the processing
- if (ajaxObject.responseText == '1') { // if the result is 1
- alert('Welcome back!');
- }
- else { // otherwise
- alert('Nice to meet you, stranger!');
- }
- } // end if
- else { // if the status code is anything else (bad news)
- alert('There was an error. HTTP error code ' + ajaxObject.status.toString() + '.');
- return; // exit
- }
- } // end if
- // if the ready state isn't 4, we don't do anything, just
- // wait until it is...
- } // end function ajaxResponse
Integrating the script and the page
We need to make some minor changes to our index.php to make it JavaScript enabled. I’ll repost everything from <body> down to the bottom (you’ve added that JavaScript, right?!).
- <body>
- <form name="ajaxform" method="get" action="javascript:;" onsubmit="doAjaxQuery('ajax.php?name=' + document.getElementById('name').value);">
- Name: <input type="text" name="name" id="name" value="" /><br /><br />
- <input type="submit" value=" OK " />
- </form>
- </body>
- </html>
So if we enter Bob as the name, the URL JavaScript would query would be ajax.php?name=Bob (filling in the name for us).
OK at this point your script should work, so try it out with both the names in the list and some random names too to make sure it comes out with the right response.
(If you’re having trouble, download the completed files that I’ve tested that work below).
Looking in the internals
So let’s just recap exactly what happens from the point of view of the first page.
- The user loads the first page and enters a name into the box called name.
- The user submits the form, which kicks doAjaxQuery into action.
- doAjaxQuery sets up an Ajax request and submits it (to a URL containing the contents of name).
- We wait until ajaxObject.readyState is equal to 4.
- ajax.php responds and checks to see if the contents of name it has been given is in the list.
- If there is a match, PHP responds 1, otherwise 0.
- JavaScript takes this response and displays an appropriate message.
Wow, that’s done! If you followed this correctly, you should now have a very simple Ajax application! Armed with this knowledge you should now be able to adapt this code to do something maybe a bit more complex. In fact, you can do quite a lot without even touching XML.
In a future tutorial, I’ll be looking at parsing XML with JavaScript, so we can do more complicated actions with the responses sent by our server. We’ll be looking at building our own XML tags to inform JavaScript of what exactly is going and transmit a bit more information between Ajax requests.
If you want a copy of the completed script, download the files below.
Download .tar.bz2 | Download .zip
Homework
If you feel like exploring a bit more, you could try doing these things:
- Create a div and instead of popping an alert box, place the message inside that div.
- Add a box for age and also use ajax.php to check that age is within a range of acceptable ages. Use another value (2 for example) to indicate this check has failed. Modify the JavaScript to display an appropriate message.
- Change the script to do something completely different!
For the upcoming JavaScript-heavy tutorials, I’d seriously recommend investing in a developer browser plugin.
If you’re a Firefox user, try FireBug. It’s free of course, and not only does it feature a great JavaScript debugger, but a CSS and DOM inspector and the ability to spy on Ajax requests (useful for debugging your Ajax applications).
If you’re not on Firefox, unfortuantely I don’t have any links, but post your favourite developer plugins for the rest (and FF ones too) in the comments.
Feedback feedback feedback!
As with all my tutorials, if you’ve got any suggestions, had a few problems or you genuinely found this useful, I’d love it if you’d drop a comment on this post, it makes writing these so worthwhile!
It took me about 21/2 hours to do the main part of this tutorial, so really, any feedback is really appreciated. If this helped you, please drop a comment as it keeps me motivated to write more!
Equally, if you’ve had problems getting my code to work, comment and I’ll see if I can help you out.
Heh, thanks for reading this far(!)