Monday, October 21, 2013

Building your first Ajax application with PHP

Greetings and welcome to an all-new tutorial series, Peter’s Webdev Workshop. This tutorial series will focus on web development, mainly focusing on using PHP as a server-side language, but I’m not ruling out having a crack at Python or Ruby, ASP.NET/Mono C# or something like that. This series will also look at JavaScript on the client side and we’ll be using XHTML for all the markup.
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!’.
Now this isn’t particularly groundbreaking. If you wanted, you could do it in JavaScript alone, but that’s not the point. Once you know how to do this, you can adapt this to do something a bit more interesting.
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).
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  5. <title>First ever Ajax application with PHP</title>
  6. </head>
  7. <body>
  8. <form name="ajaxform" method="get" action="#"><!-- leaving the action to do nothing for now -->
  9. Name:&nbsp;&nbsp;<input type="text" name="name" value="" /><br /><br />
  10. <input type="submit" value=" OK " />
  11. </form>
  12. </body>
  13. </html>
Building the backend
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.
  1. <?php
  2.  
  3. // Part of a tutorial by Peter Upfold
  4. // Released under the Modified BSD Licence:
  5. // http://www.opensource.org/licenses/bsd-license.php
  6.  
  7. session_start(); // start a session
  8.  
  9. header("Content-type: text/plain");
  10. // this is only plain text, so set the HTTP header accordingly
  11.  
  12. $names = array( // this is our array of names - feel free to change/add as required!
  13. 'Bob',
  14. 'Jim',
  15. 'Mark',
  16. 'Graham'
  17. );
  18.  
  19. if (in_array($_GET['name'], $names)) { // if that name is in our array above
  20.  
  21.     echo '1'; // echo 1 (tells JavaScript we know this person)
  22.  
  23. }
  24.  
  25. else { // otherwise
  26.  
  27.     echo '0'; // echo 0
  28.  
  29. }
  30.  
  31.  
  32. ?>
So let’s just test it first without the Ajax. Put these files in a web-accessible place, and then pop open your favourite browser and go to (if you’re running a local Apache/IIS server) http://localhost/wherever/you/put/it/ajax.php?name=Bob. You should simply receive a 1 in response, which is correct.
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.
  1. var ajaxObject = false;
  2. // this is our object which gives us access
  3. // to Ajax functionality
  4.  
  5. function doAjaxQuery(url) {
  6.  
  7.         ajaxObject = false;
  8.  
  9.     if (window.XMLHttpRequest) { // if we're on Gecko (Firefox etc.), KHTML/WebKit (Safari/Konqueror) and IE7
  10.        
  11.         ajaxObject = new XMLHttpRequest(); // create our new Ajax object
  12.  
  13.         if (ajaxObject.overrideMimeType) { // older Mozilla-based browsers need some extra help
  14.             ajaxObject.overrideMimeType('text/xml');
  15.         }
  16.    
  17.        
  18.     }
  19.     else if (window.ActiveXObject) { // and now for IE6
  20.             try {// IE6 has two methods of calling the object, typical!
  21.  
  22.             ajaxObject = new ActiveXObject("Msxml2.XMLHTTP");
  23.             // create the ActiveX control
  24.  
  25.  
  26.         } catch (e) { // catch the error if creation fails
  27.  
  28.             try { // try something else
  29.  
  30.             ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
  31.             // create the ActiveX control (using older XML library)
  32.  
  33.  
  34.             } catch (e) {} // catch the error if creation fails
  35.         }
  36.     }
  37.  
  38.         if (!ajaxObject) { // if the object doesn't work
  39.  
  40.             // for some reason it hasn't worked, so show an error
  41.  
  42.         alert('Sorry, your browser seems to not support this functionality.');
  43.  
  44.         return false; // exit out of this function
  45.         }
  46.  
  47.    
  48.         ajaxObject.onreadystatechange = ajaxResponse; // when the ready state changes, run this function
  49.  
  50.     // DO NOT ADD THE () AT THE END, NO PARAMETERS ALLOWED!
  51.  
  52.     ajaxObject.open('GET', url, true); // open the query to the server
  53.  
  54.         ajaxObject.send(null); // close the query
  55.  
  56.     // and now we wait until the readystate changes, at which point
  57.     // ajaxResponse(); is executed
  58.  
  59.     return true;
  60.  
  61.     } // end function doAjaxQuery
  62.  
  63. function ajaxResponse() { // this function will handle the processing
  64.  
  65.     // N.B. - in making your own functions like this, please note
  66.     // that you cannot have ANY PARAMETERS for this type of function!!
  67.    
  68.     if (ajaxObject.readyState == 4) { // if ready state is 4 (the page is finished loading)
  69.  
  70.         if (ajaxObject.status == 200) { // if the status code is 200 (everything's OK)
  71.  
  72.             // here is where we will do the processing
  73.  
  74.             if (ajaxObject.responseText == '1') { // if the result is 1
  75.  
  76.                 alert('Welcome back!');
  77.  
  78.             }
  79.  
  80.             else { // otherwise
  81.  
  82.                 alert('Nice to meet you, stranger!');
  83.  
  84.             }
  85.  
  86.         } // end if
  87.  
  88.         else { // if the status code is anything else (bad news)
  89.  
  90.             alert('There was an error. HTTP error code ' + ajaxObject.status.toString() + '.');
  91.             return; // exit
  92.  
  93.         }
  94.  
  95.     } // end if
  96.  
  97.     // if the ready state isn't 4, we don't do anything, just
  98.     // wait until it is...
  99.  
  100.  
  101. } // end function ajaxResponse
As you can see, for now we simply pop up a message and don’t do anything particularly special, but that’s OK for now.
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?!).
  1. <body>
  2. <form name="ajaxform" method="get" action="javascript:;" onsubmit="doAjaxQuery('ajax.php?name=' + document.getElementById('name').value);">
  3. Name:&nbsp;&nbsp;<input type="text" name="name" id="name" value="" /><br /><br />
  4. <input type="submit" value=" OK " />
  5. </form>
  6. </body>
  7. </html>
Notice that above, I call doAjaxQuery with one parameter, the URL to send the data. This is simply ajax.php, plus the query mark ?, then name=. After this, we ask JavaScript to get the value of the name field and stick it at the end of the URL.
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.
We’re done (almost)
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!
Resources
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(!)