Pages

Banner 468

Wednesday, 13 April 2011

Building a Web space Management System 1

0 comments
 
Hello again. As I explained way back in my very first post I am a Middlesex University student studying for a degree in Internet Application Development. The purpose of this blog has been to share my thoughts and experiences on the practical work I've been carrying out during this course.

During my next few posts, I will be building a small Web space management System using PHP.

Task Definition

The aim of this task is to 'write a Web space management system suitable for handling Web site content of various types. It should allow users to add and organise files to a personal Web area which is secured by a password.'  The 'program' should support the following features:
  • Passwords are to be stored on a MySQL database
  • Authenticated users should be able to craete/upload/delete files and directories
  • Users should only be able to access their own space
  • Space quotas (limits)
We have our requirements, so let's get started!

1. The Login Form

The first step is to create a login form for our users. Later on in the series (when tackling MySQL connections) I will create a proper user registration form, but at this stage I will assume that I already have some registered users.  The login form accepts a username and a password (obviously) and will support a "remember me" feature. I've used HTML & CSS techniques discussed in my earlier posts to style the form. 

Here's what it looks like:


I've also added some simple javascript validations to prevent the form from being submitted if either the username or the password is left blank. However, it is always a good idea to duplicate such validations on the server as well since we have no way of knowing whether javascript is enabled on the client's browser!
I want to place these server-side validations on the login page itself so I have set the 'action' attribute of the login form to request itself. I don’t want to hard-code the name of the page so I will be using PHP to set the value of the “action” attribute of our form. Here’s one way of doing this:

<form action="<?php echo $_SERVER['SCRIPT_FILENAME'] ?>" method="post" id= ... >

We could also use ‘PHP_SELF’ instead of ‘SCRIPT_FILENAME’ however, as explained by Luke Visinoni in this article, this variable 'cannot be trusted' as it is vulnerable to cross-site scripting attacks. Using ‘SCRIPT_FILENAME’ is a safer option.

Next we add the PHP validations just below the "body" tag:

<?php
   $ErrMsg = "";  
   //Execute only if the page has been posted back (not first time load)
   If ($_SERVER['REQUEST_METHOD'] == 'POST')
   {
      //Validate user input: username and password must not be blank  
      if ($_POST['txtUname'] != "" && $_POST['txtPassword'] != "")
      {
        //Authenticate the user
      }
      else 
      {
        $ErrMsg = "Please enter a username and password";  
      }
   }
?>

Since we are posting to the same page, we want to prevent validations and subsequent authentication logic from executing when the page is loaded for the first time. At line 5, the script checks the request method of the page and will only execute the rest if it is set to ‘POST’. Assuming that the client will use a GET method when requesting the page for the first time this method will work fine. There are other techniques which could be used but for the sake of simplicity we’ll stick to this method. I must say however that at this stage I have yet to find a ‘fool proof’ method for doing this check as all the ones I came across have some kind of drawback. I guess avoiding posting to the same page or better still use an MVC framework would be a better solution but for now checking the request method will do nicely.

2. Server-Side Validation & Authentication

The previous code listing includes the first validation I want to add to the form, i.e. making sure that both the username and password are not left blank. Looking at line 8, ‘$_POST’ is a global associative array of variables which are passed to the script whenever a page is posted. It will contain the values of all the input fields in the submitted form. In our case, ‘txtUsername’ and ‘txtPassword’ are the names of the text boxes (HTML input type=text) for the username and password respectively. The names of these fields are set as keys in the $_POST associative array through which we can get to the actual values (See my previous post for more information on associative arrays). If either the username or password is left blank, the script sets the ‘$ErrMsg’ variable to the appropriate error message which is then ‘echo’ed to the user further down the page:


As I mentioned earlier, I am assuming that I already have some registered users. By that I mean that I have hard-coded a username and password in the script to represent values returned from a database. I will come back to this script later on in the series when I set up a proper registration page and store user accounts on a MySQL database. At this stage I wanted to focus on how to redirect authenticated users to the ‘private’ area and how we can use cookies/sessions to ‘remember’ a user. So, building on the previous script:

…
//Validate user input: username and password must not be blank  
if ($_POST['txtUname'] != "" && $_POST['txtPassword'] != "")
{
   //Authenticate the user
   define ("User", 'guest');
   define ("Pass" , 'letmein');
   if($_POST['txtUname']==User And $_POST['txtPassword']==Pass)
   {
      header("Location: http://localhost/PHPLabs/private.php");
   }   
   else 
   {
      $ErrMsg = 'Incorrect username or password';
   } 
}
else 
… 

After checking that the username and password are valid (against my hard-coded values) the ‘header’ function is called which sends a raw HTTP header to the browser causing the redirection to the selected page (private.php in this case). Pretty simple, however there’s a catch or rather two of them. First, any code after the header function will still be executed! In our case this is not that big of a problem as the script is quite small, however larger scripts would take longer to execute and consume more resources. Depending on how popular your site is and how many hits/requests it gets, these ‘wasted’ resources could have a negative effect on performance. To avoid this problem we can simply call to the ‘die()’ function after the redirection which will prevent the rest of the script from being executed. Secondly, the ‘header()’ function must be called before any kind of output is sent to the browser, including HTML tags, echo and print functions, otherwise it will not work. However you can use PHP output buffering to avoid this:

//Authenticate the user
define ("User", 'guest');
define ("Pass" , 'letmein');
if($_POST['txtUname']==User And $_POST['txtPassword']==Pass)
{
   ob_start();
   echo “Testing output buffering”;
   header("Location: http://localhost/PHPLabs/private.php");
   ob_flush();     
}   
else 
{
   $ErrMsg = 'Incorrect username or password';
} 
… 

The ‘ob_start()’ function turns on output buffering which will prevent the script from sending any output – except for headers – until ‘ob_flush()’ is called, so in this case no error is reported.

3. Using Sessions

Up to this point we have successfully redirected the user to the ‘private.php’ page after entering a valid username and password. However, ‘private.php’ still needs to verify that the user has been authenticated; otherwise all requests made to the page would be accepted! We need a way of persisting the ‘authenticated’ state until the user logs out or closes the browser. Here’s where sessions can help. Sessions are a combination of a client-side cookie and a server-side cookie where the former only contains a reference to the latter. For this reason, sessions are more secure than traditional cookies since the client has no means of changing important data stored within the cookie. Take a shopping cart for instance. If the shopping cart data was stored in a cookie on the client, the user could easily change the price (for example) of a given item before checking-out! Using cookies in this scenario is bad enough, placing something such as the price within that cookie is just asking for trouble.

Back to our scenario, we want to store a flag indicating that the user has been authenticated within a session variable such that it is accessible by every page in our private or member’s area. Here’s how it’s done:

session_start();
…
//Authenticate the user
define ("User", 'guest');
define ("Pass" , 'letmein');
if($_POST['txtUname']==User And $_POST['txtPassword']==Pass)
{
   $_SESSION['loggedin'] = 1;
   $_SESSION['userid'] = $_POST[‘txtUname’];
   header("Location: http://localhost/PHPLabs/private.php");
   die()
}   
else 
{
   $ErrMsg = 'Incorrect username or password';
} 
… 

We first need to place a call to ‘session_start()’ at the beginning of our PHP script (line 1). This will inform PHP that we intent to use sessions and to expect the use of session variables. Next, we use two session variables to store the flag indicating that the user has been authenticated as well as the username itself. As you can see, session variables in PHP are stored in an associative array called $_SESSION.

We now want to make sure that the private.php page checks for these session variables. This will ensure that when requesting the private page directly the client is redirected to the login page for authentication:

session_start();

if (isset($_SESSION['loggedin']))
{
   echo "Welcome ".$_SESSION['userid']; 
}
else 
{
   header('Location: http://localhost/PHPLabs/Forms.php');
   die();
}

Once again we should start the script by calling the session_start() function to gain access to the session variables which are then checked. If the ‘loggedin’ variable is set, the user is granted with a welcome message but otherwise redirected to the login page.

Finally, I will add a ‘logout’ button that will end the user’s session gracefully. The button simply calls the logout.php script which closes the session and redirects the client to the login page:

<?php
   //logout.php;
   session_start();
   session_unset();
   header("Location: http://localhost/PHPLabs/login.php");
   die();
?>

It might look odd that the scripts calls the session_start() function just before calling session_unset(), however it will not work otherwise. Remember that session_start() not only checks for an existing session and creates one if it finds none but it also gives the script access to the session variables. In essence, session_unset() would have nothing to unset unless session_start() is called beforehand! A bit confusing at first bit it does make sense when you think about it.

Wrapping up


That's it for this post.  We have seen how to create a simple login form and how to add server side validations to validate user input and authenticate the user.  We've also seen how we can redirect the client to the private area after authentication and how to use sessions to our advantage.  I haven't implemented the "remember me" check box yet, but I will be doing so when discussing cookies and personalisation later on in the series.

Overall, this exercise is helping me gain a clearer picture of  what PHP is all about.  In it's raw state its much more low level than what I'm used to (ASP.Net) but I've found it to be simple to learn, easy to use and fast performing. Also, the sheer amount of information about PHP on the Web can be quite overwhelming and sometimes contradictory.  I've found that - just like seeking medical advice - it's best to get a second opinion before embracing a concept.  As stated in my previous post, PHP is easy to learn but it is even easier to learn coding it badly.

My next post will focus on how to connect our PHP pages to a MySQL database and how to authenticate our users properly against that database.
Readmore...
Sunday, 10 April 2011
0 comments
 

Server-Side Languages 2 - Basic PHP


In my last post, we looked at how to use XAMPP to set up an Apache web-server that includes MySql and PHP.

This post will focus on the PHP server-side language itself and how we can use it to generate dynamic web pages.

What is PHP?


PHP is a free, platform independent scripting language originally developed way back in 1995 specifically for creating dynamic web pages. PHP originally stood for “Personal Home Page”, however it is now widely accepted that PHP is a recursive acronym standing for “PHP: Hypertext Preprocessor”. Whatever the meaning, PHP has grown into one of the most popular scripting languages in use today.

As with any programming language, the best way to learn/explain how it works is through practical examples. During this post I will introduce basic PHP syntax and how to use variables, arrays and loops to create (step-by-step) a simple page that dynamically displays a list of usernames and passwords.

Step 1 – “Hello World”


The following snippet shows a simple HTML page with some embedded PHP code between the '<?php' and '?>' tags.  Any text between these tags will be interpreted by PHP on the web server before sending the page to the client (web browser).  In this case,  we are using the 'print' PHP construct to place "Hello World!" between the <h1> tags.  Furthermore we are using a double forward slash (//) to add a single line comment to the script.

<html>
      </head></head>
      <body>
         <h1>
            <?php
               //Display "Hello World!" between h1 tags
               print "Hello World!";
            ?>
         <h1>
      </body>
   </html>

We could also use 'echo' instead of 'print' to produce the same effect. So what's the difference? Basically both 'echo' and 'print' are PHP constructs that output text to the screen but the difference lies in how they are structured and not what they do. Basically the 'print' construct returns a value, just like a function, while 'echo' does not. What this means is that when looping through an extended amount of iterations, 'echo' performs faster than 'print'.

Step 2 - Variables

PHP is a loosly-typed language meaning that we do not need to specify a datatype when declaring variables.  In the following code snippet, I will create two variables to store values for a username and a password and use the echo construct to display these values to the user:

<html>
   <head></head>
   <body>
      <?php
         /*
           Declare variables.  
           All variables in PHP start with a '$' sign
         */
         $Uname = 'guest';
         $Pword = 'guest123';            
            
         echo "Username: ".$Uname."<br>";
         echo "Password: ".$Pword;

      ?>
   </body>
</html>

Pretty straight forward so far. One thing of note however is how the value of a variable is being concatenated to the rest of the string. In PHP the concatenation operator is the '.' rather than the more commonly used '+'.

Before going onto arrays I would like to demonstrate how to replicate the above example using constants rather than variables. Constants are 'special' variables whose values cannot change, or remain constant (hence the name). Here's how the above example would look like when using constants:

<html>
   <head></head>
   <body>
      <?php
         /*
            Define constants.  
            The value of a constant cannot be changed
         */
         define ('Uname', 'guest');
         define ('Pword', 'guest123');        
         
         echo "Username: ".Uname."<br>";
         echo "Password: ".Pword;
      ?>
   </body>
</html>

Constants are defined using the 'define()' function, passing the name of the constant and its value as parameters. Unlike variables, names of constants must start with a letter or an underscore and are - by default - case sensitive (like the rest of the language for that matter).

Step 3 - Arrays


In PHP we can use three kinds of arrays:

  • Numeric Arrays
  • Associative Arrays
  • Multidimensional Arrays

I have already discussed numeric arrays in detail in previous posts so I will focus on Associative Arrays instead (We'll tackle multidimensional arrays in my next post).

An associative array is basically a collection of key-value pairs whereby we can retrieve a specific value based on a string key rather than a numerical index. Associative arrays are used extensively in PHP: $_REQUEST, $_SESSION and $_COOKIE are all examples of pre-defined associative array variables. $_COOKIE for instance is an associative array that stores variables passed to the script through HTTP cookies. We will see these (and more) of these pre-defined variables in action in the next post, but for now we will see how we can define and use our own associative arrays.

As mentioned at the beginning of this post, I want to create a script that displays a table of usernames and passwords to the user. In the next code listing, I will define an associative array to store my username and password 'pairs':

<html>
   <head></head>
   <body>
      <?php
         // Define the associative array
         $users = array("admin"=>"admin123",
                        "user1"=>"letmein",
                        "guest"=>"guest100,"
                        "Wimpy"=>"hamburgers");
      ?>
      <h3>User List</h3>
      <table border="1">
         <tr>
            <th>Username</th><th>Password</th>
         </tr>
         <tr>
            <?php 
               echo "<td>admin</td>";
               echo "<td>".$users['admin']."</td>";
            ?>
         </tr>
         <tr>
            <?php 
               echo "<td>user1</td>";
               echo "<td>".$users['user1']."</td>";
            ?>
         </tr>
         <tr>
            <?php 
               echo "<td>guest</td>";
               echo "<td>".$users['guest']."</td>";
            ?>
         </tr>
         <tr>
            <?php 
               echo "<td>Wimpy</td>";
               echo "<td>".$users['Wimpy']."</td>";
            ?>
         </tr>
       </table>
   </body>
</html>

Best practices apart, the above example demonstrates how to define an associative array (line6) where the key-value pairs are the usernames and passwords respectively. Simple echo statements are used to display the users as an HTML table. This is obviously not the best way to do this. One of the advantages of arrays is that they allow us to iterate through their values, which brings us to the final topic of this post:

Step 4 - Looping Through Associative Arrays


As we have seen, associative arrays are based on string values (keys) rather than numeric indices which means that we cannot use a counter in a for loop to iterate through the array. We can however use the foreach loop or the each() and list() constructs instead.

Method 1 - The Foreach Loop

<?php
   // Define the associative array
   $users = array("admin"=>"admin123",
                  "user1"=>"letmein",
                  "guest"=>"guest100",
                  "Wimpy"=>"hamburgers");
?>

<h3>Method 1 - Simple Foreach</h3>
<table border="1">
   <tr><th>Username</th><th>Password</th></tr>
   <?php  
      foreach($users as $username => $password)   
         echo "<tr><td>".$username."</td>";
         echo "<td>".$password."</td></tr>";
   ?>

</table>
In this method, we use a simple foreach loop to iterate through each username and password pair. During each iteration, the values of the current element in the array copied into the '$username' and '$password' variables respectively which are then used in the echo statements further down.
Method 2 - Using the 'each()' construct
We can also use the each() construct within a while loop to iterate through the array. Each() will return the current key and value pair as a four element array which allows us to get the value either through the key or through a numeric index. Using our $users array as an example, the first time 'each($users)' is called, the returned array, say $user, would look like this:
$user
(
[0] = 'admin'
[key] = 'admin'
[1] = 'admin123'
[value] = 'admin123'
)

Here's what the code looks like when using 'each()':

<?php
<h3>Method 2 - Using the each() construct </h3>

<table border="1">
   <tr><th>Username/th><th>Password</th></tr>
   <?php
      while($user = each($users))
      {
         echo "<tr><td>".$user['key']."</td>";
         echo "<td>".$user['value']."</td></tr>";
      }
   ?>

</table>
Since the 'each()' construct sets the array cursor to the next element in the array (or beyond), you must use the 'reset()' function to use the array with 'each()' again.
There is however a more common way of using 'each()' which also easier to understand:

Method 3 - Using 'each()' and 'list()'

while (list($uName, $pass) = each($users))

The above statement executes the 'each()' function to get the current key-value pair of the $users array and makes the next element current. The 'list()' function takes the [0] and [1] elements of the array returned by 'each()' and places the values into variables named '$uName' and $pass. We can then 'echo' the values of these variables as usual.

Conclusion

During this rather lengthy post we have taken a look at some baisc PHP and how we can use this popular scripting language to generate some dynamic content on the server. Being an ASP.net developer myself, this was my first experience in working with PHP. I must admit that although PHP is easy to learn, the lax nature of the language allows for some really bad-practice coding. The real challenge in my opinion is not learning the PHP syntax itself, but rather learning how to use it well in a disciplined and ordered manner. Raw PHP reminds me of the old ASP days where the notion of separating code from markup was something we fantasized about. Full-blown ASP web applications were a nightmare to maintain due to the way code and markup was intertwined in true spaghetti fashion.
There are however patterns and frameworks that help mitigate this problem and I will definitely look into them in the near future.
In my next post, I will be building a simple login page and use PHP to 'authenticate' users and we will also look at how we can use and manage sessions and cookies.
Readmore...
Sunday, 27 March 2011

Server-Side Languages 1

0 comments
 
To date, most of my blogs have dealt with topics related to the client-side aspect of web development.  We looked at some basic HTML, how to style our pages using cascading style sheets (CSS) and how to add dynamic content using javascript.  It's now time to divert our attention to the server-side, specifically server-side scripting using PHP.

Server-Side?

Before tackling server-side scripting let's take a step back and have a high level look at how the web works.  Whenever you navigate to a new web page, your browser is effectively sending an HTTP request to a web-server over port 80.  The server then responds by sending the requested web-page or an error message (if the page was not found for instance) which the browser then displays.  This is known as the client-server model where the client is your browser and the web server is, you guessed it, the server.  Server-side scripting is a technique where the server executes some code (scripts) while processing a request to generate dynamic content  which is then sent back to the browser.

There are many server-side languages such as ASP, PERL and PHP and others.  The choice on which to use largely depends on your what you're trying to achieve and what would be best suited to your current environment.  There are other aspects to consider such as platform in/dependence, interoperability with other systems (e.g. databases) and security.  Having said that, any detailed comparisons between technologies goes beyond the scope of this blog which will instead focus on PHP.  

At this stage I would like to emphasize that I have just started learning PHP (my professional background lies in ASP and ASP.Net) and that the purpose of my next couple of posts is to share this learning experience.  This first post will mainly focus on how I went about setting up my development environment.

Setting-Up

First thing I did was to visit www.apachefriends.org to download the XAMPP installer.  XAMPP is a distribution of the popular Apache web-server that also includes MySQL, PHP and Perl.  This will spare me the headache of manually configuring Apache with MySql and PHP.

Given that I wanted to simulate the client-server model on my machine I installed XAMPP on a virtual machine which will act as my web-server.  This is where I hit my first hiccup.  The virtual machine I'm using as a web server is running MS Windows Server 2008 with User Account Control (UAC) turned on for security.  The XAMPP installer promptly suggests that, given the security constraints imposed by UAC, I should either disable UAC or install XAMPP to a location other than the "Program Files" folder.  Naturally I opted for the latter as I was not particularly inclined to disable UAC so I installed XAMPP to "C:\XAMPP" on my virtual disk.

First Contact

Once the installation was complete, I went ahead and started the XAMPP control panel and I immediately ran into another problem.  The control panel reported that it should only be run from the XAMPP root directory (Status Check Failure [3] error), which in my case is "c:\XAMPP\" which is exactly where it was being executed from!  I cleared the error message and attempted to start the Apache service from the contol panel with no success.  I noticed that the control panel was attempting to start Apache on port 80 and it suddenly dawned on me that I had to change the port number since I had IIS (this is a windows server after all) listening on port 80.  To change the port number bound to Apache:

  • Open c:\xampp\apache\conf\httpd.conf file.
  • Find and change the "Listen 80" entry to "Listen 8080" (8080 is the port I chose) 

I once again attempted to start apache but it still would not work.  At this point I referred to the Apache Friends forum to see if the problem was related to the "Status Check Failure [3]" error  I was getting when starting the XAMPP control panel.  Strangely enough, the solution I found was to uninstall XAMPP, and "re-install" it by downloading and extracting the "ZIP archive" version to the same root directory as before (c:\xampp).  Once again I changed the port number and started the XAMPP control panel.  This time no error was reported and Apache started successfully.

Testing the installation

Following that strange solution I wanted to make sure that everything was running as expected.  I started the browser and navigated to "http://localhost:8080" which thankfully displayed the XAMPP default page.

Next I verified that all the necessary components (MySql, PHP, SSL, SSI and FTP) were working correctly by browsing to the XAMPP Status page:

XAMPP Status page showing component status
I also accessed the XAMPP Security report and realised that by default, everything is unsecured, something I will definitely tackle sometime soon.  Further checks included having a look at the PHPInfo report and making sure that the sample guest-book worked correctly, which it did.

Summing Up

All in all this was quite a different experience for me.  I have never used, let alone configured Apache before since my professional experience lies in MS Internet Information Services (formerly Internet Information Server) and ASP/ASP.Net.  Besides that strange "root directory" error and its equally strange solution, installing and configuring Apache with MySql and PHP proved to be very easy using XAMPP and I'm considering setting up another virtual web server, this time using Linux to compare the installation process and results.  I'm especially curious what the default security settings would be on Linux.

In my next post, I will be customising the XAMPP default web page and attempt to access the web server from my host machine.


Readmore...
Thursday, 17 March 2011

My Two Cents on Accessibility

0 comments
 
I had the opportunity today to listen to a very good presentation on accessibility and how websites can be made more accessible.  The key word here is 'can'.  Indeed you can and should make your website more accessible for two simple reasons.  First of these is a no-brainer, accessibility means just that, making your pages accessible to a wider audience.  Secondly however, most of the techniques and tricks used to increase accessibility are also best practice:
  • Table-less layouts - better for screen readers but also helps separate content from layout
  • Clear and meaningful 'alt' and 'title' tags - a must for screen readers but also provide useful tooltips
  • Correct use of  HTML headings - good semantics = better structure = better accessibility
  • and so on 
I always thought of accessibility from a visually impaired person's perspective.  However, after today's presentation, I've come to realise that vision is not even half the story.  Cognative disabilities, motor disabilities as well as hearing impediments must also be considered when working on improving your website's accessibility.  Providing adequate space between elements is something I often overlook but is vital to someone with motor disabilities.  Flashing colours, animations, tickers, sudden sounds can all prove to be too much for persons that have trouble concentrating.  And its not just a case of providing a text only version of your page.  Most people still want to enjoy the whole experience of the website, they just want more control over the page.  Providing functionality to stop tickers or turning off sounds doesn't take much and goes a long way to improving the user experience. 

I also had the opportunity to see some clips of people with various disabilities speaking about their experiences and wanting to smash the computer out of frustration.  This was a real eye opener for me.  Speaking to such people and having them test your website is now in my opinion invaluable in getting the right feedback about the experience your website provides.


Readmore...

XML Basics

0 comments
 
In today's post I will be discussing the basics of XML and why it has become so important for the web.

What is XML?
XML stands for eXtensible Markup Language and was primarily designed as a means of "carrying" or storing data.  As its name implies, XML is a markup language which means that "tags" or "elements" are used to structure the data within the document.  In contrast to HTML (another markup language), where elements are pre-defined, in XML you define your own elements.  Consider the following example where we would like to store the following information about student projects as an XML document:
  • Student Name
  • Student ID
  • Project Title
  • Project Category
  • Project Abstract
  • Date Submitted
One way of structuring this data in XML would be the following:


In the example above, an element was defined for each data item that we needed to store and the actual data is placed between each element's opening and closing tags.  You may also notice that the <project> tag encapsulates all of the other elements.  Besides giving more meaning to the data, this element is also necessary because an XML document must always have one root element (more on validation later).

Taking it Further
In the previous example we can see that "student_name" and "student_id" both relate to a student while the rest of the elements relate to the project.  Also, since an XML document can only have one root element, the current structure prevents us from storing information about multiple projects.  With this in mind, here's a better way of structuring the document:


By adding the <projects> root element we can now have multiple <project> elements within the document and student-related information has also been nested (grouped) within the <student> element.  Finally, the <date_submitted> element has been broken down further into the <day>, <month> and <year> elements, which at first glance seem superfluous.  Consider however a scenario where you wanted to share this data with another system over the web. This system may or may not have the same date format as your system.  Breaking down the date into its constituent parts makes sure that the date is interpreted correctly.  I'll be discussing the advantages and practical uses of XML later on in this post.

XML Attributes
We have already seen how to define and use XML elements, however XML elements can also have attributes (like HTML).  Attributes are generally used to store information about the data within the element - I like to think of attributes as an element's metadata.  Attribute values must be enclosed within quotes and defined within the element's opening tag, just like in HTML.  Taking the previous example, the project category can be considered to be information describing the type of project and is a good candidate for an attribute:


Here, the category elements have been replaced by the category attributes of the project elements.  There is no real difference between the two examples as both XML documents contain the same data.  So when should we use attributes?  Opinions on the subject vary.  Some say that XML attributes are useful others say that they should be avoided.  My view is that it all depends on how extensible you want your XML document to be.  Keep in mind that XML elements can be nested, so an element that today holds a single value can be changed to store multiple values some time down the line.  Conversely, XML attributes can only store one value and will have to be changed to elements if the need to store multiple values arises which may have an adverse effect on systems that consume your XML documents.  In a nutshell, some careful planning and thinking ahead needs to be done when deciding between elements and attributes.  My rule of thumb is to use elements whenever in doubt.

Basic XML Validation using DTD
An XML document having correct syntax is said to be "Well Formed" but is not necessarily valid.  Besides being well formed, an XML document must also follow rules that define its structure for it to be valid.  One way of defining the structure of an XML document is by using a Document Type Definition (DTD).  XML documents can also be validated using XML Schemas but for the sake of simplicity, I will only be loking at DTDs in this post.  

A DTD defines the structure of the XML document by providing a list of elements and attributes that are valid or "legal" within the XML document.  Using the projects XML document discussed above as an example, the following DTD can be used to validate the document:

Line 3 states that this DTD applies to the "projects" document type which is our XML document root element.  Lines 5 to 16 list the legal elements that are expected within the XML document. Looking closer, Line 5 states the projects element (our root element) must have one or more occurances of the <project> element (the '+' sign indicates one or more).  Similarly line 6 states that the <project> element must have exactly one occurance (no '+' sign) of each of the <student>, <title>, <abstract> and <date_submitted> attributes.  The DTD also specifies that the lowest level elements such as id, name and surname contain PCDATA or Parsed Character data. In other words, the values of these elements will be parsed by the XML parser to check for entities and other markup.  Conversely, if CDATA (Character Data) was used,  the values would not be parsed and accepted as is.  Line 18 also specifies that the <project> entity must have (#REQUIRED) a "category" attribute of type CDATA.

The DTD can be defined within the XML document (as the example above) or as a separate file.  If used as a separate file, the <!DOCTYPE>" declaration should be written as "<!DOCTYPE projects SYSTEM 'DTDfilename'>".

The Importance of XML
As hinted earlier in this post, the fact that XML is text based makes it a truly platform independent way of storing and sharing data.  This is especially important for sharing data between applications over the web, where more often than not these applications are incompatible with one another.  XML also makes your data more available, in the sense that it can be consumed by any number of services and devices.  XML is also being used to create new languages.  XHTML, RSS, WSDL and more recently XAML are all based on XML.

Just the Beginning
In this post, we have just scraped the tip of the proverbial "iceberg" with respect to XML.  There are many other topics to explore including XML Transformations, XML Schema Validation, XML in web services and many more.  Hopefully, I will have the opportunity to cover XML in more detail in future posts.



Readmore...
Wednesday, 9 March 2011

Javascript Animation 2

0 comments
 
In my last post I built a simple animation of a man running around a webpage.  We also saw some simple collision detection techniques to make the man bounce off the edges of the screen.

In this post, I will continue building on this project by adding functionality to throw obstacles at the runner.   I also want the runner to change direction after hitting an obstacle and the obstacle itself should disappear after being hit.

Adding Obstacles

The first thing we need to do is write a function that places an obstacle on the screen.  To do this we need to access the document object and append image elements (representing obstacles) to the DOM tree.   
The 'createObstacle()' function above creates a new image element at line 134 and sets various attributes such as the image source and css class name using the setAttribute() javascript function.  The 'obstacle' css class specifies that the image is 50px square in size and that it is absolutely positioned on the screen.  Using the Math.random() function I generate co-ordinates to position the obstacle randomly on the screen.  I also randomly select the image source of the obstacle from the pre-defined 'obstacles()' array.  Finally I append the new image to the 'canvas' <div> using the appendChild() method.  Finally I can wire this function to the 'place obstacle' button in the control panel.  Now, every time the button is pressed, a random obstacle is placed on the screen.
More Collision Detection
I want my runner to change direction when he 'hits' an obstacle and I also want that obstacle to disappear with a bang!  Here's the modified collisionDetect() function first introduced in my previous post:



The first thing I do in the obstacles section of this function is to get an array of all the images contained in the canvas <div> using the getElementsByTagName function.  Next I loop through the array and if the image is an obstacle I compare its co-ordinates to that of the runner.  If they intersect I call the 'createBlast()' function, passing the obstacle as a parameter and switch the direction of the runner.  We'll now look at the 'createBlast()' function which removes the obstacle after making it 'explode'.

The idea behind the 'createBlast()' function is to display an image of an explosion instead of an obstacle just after it is hit.  I once again use the 'createElement()' javasacript function to create the blast image and set its co-ordinates to that of the obstacle being hit.  This time however I use the replaceChild() javascript function instead of 'appendChild' such that the blast image replaces the obstacle.  I want the blast image to disappear after 100 milliseconds so I use the 'setTimeout()' javascript function to trigger the 'clearBlast()' function.  I needed to pass the blast object to the 'clearBlast()' function but this cannot be done using normal syntax.  Hence I used a technique called 'closure' to get the desired effect.  Closure is one of the most powerful features of javascript and fully explaining it goes way beyond the scope of this post.  Put simply however, closure allows you to create functions within functions where the inner functions have access to all the local variables of the outer function.

Conclusion
That's it.  We now have an animation of a man running around the screen, hitting objects thrown at him and bouncing off the edges of the screen.  Here's what the finished product looks like:


During these last two poists we looked at how we can use timing functions as a basis for animation and how to manipulate the DOM tree to add and remove nodes at runtime.  We also saw how to randomise certain aspects of the functionality (such as positioning the obstacles) and even some basic collisionn detection.
Overall it was a pretty enjoyable exercise with plenty of opportunity to experiment with various javascript techniques.  I hope you enjoyed reading it as much as I did coding it. 
Readmore...
Tuesday, 8 March 2011

Javascript Animation

0 comments
 
This week, we will see how we can use javascript to create simple animations on your web page.

To demonstrate this, I'll be creating an animation of a running man where the user can:
  • control the speed of the animation
  • change the direction of the animation, and
  • throw obstacles at the runner
I will also demonstrate some simple collision detection techniques such that the animation does not 'run off' the screen but rather 'bounces off' the edges and changes direction.

The HTML

For this task I wanted to split the page into two sections, the top section will serve as a 'canvas' or boundary for the running man animation while the bottom section will display all the necessary controls.
To do this, I will create two <div> elements named 'canvas' and 'control panel' where the former will contain the running man image and the latter will contain the controls:


The controls are a combination of HTML anchor elements, styled to look like buttons, and a 'select' element to allow the user to change the animation speed from a drop-down list.  The controls are laid out using an HTML table and after some CSS styling this is what the page looks like:


The focus of this blog is the javascript code behind the animation so I will not be going into detail on how the page has been laid out and styled.  The techniques used have all been covered in my previous posts. 

The Code
As a basis for my animation I will be using 11 images (or frames) each of which is showing the man at a different 'stage' in the run.  The principle behind this animation is to change the source of the image element over time, displaying each frame in sequence, to simulate a running man.

So, let's get started.  The first thing we need is an array to store the path of each frame in the animation:

 Line 11 defines a new array called 'rightRunner' which is populated using a for loop.  Each element in the array now represents a different frame in the animation.  I chose to call the array rightRunner because initially, the man will run to the right.  

Next we need a method that will change the source of the animation image:
 Each time the marathon() method is called, the src attribute of the animation image changes to the next frame in the array.  The curRunner global variable is used to keep track of the current frame and whenever it reaches 10, it is reset to 0 such that the animation loops from the begining. For the animation to work, we need a way of triggering this method over time and the 'setInterval()' javascript method allows us to do just that.  The setInterval method requires two parameters: a reference to the function to be executed and the interval (in milliseconds) between function calls. We can also use the 'clearInterval' method to stop the animation.



The above code snippet shows the two functions I will use to start and stop the animation(s).  Since I will be adding more animations later, I'm using switch statements to determine which of these animations to start/stop.  Line 23 calls the setInterval method on the 'marathon()' function and the interval is set to the selected value of the animation speed drop-down list box.  The returned ID is stored in the runningTimerID global variable which is then used to stop the animation at line 35.  I am also using the 'isRunning' global variable to ensure that the animation is started only once.  Next I will wire these two functions to the start and stop buttons:


We now have the basic animation in place upon which we can start adding the other features.

Adding Movement

At this stage when we start the animation the man seems to be running on the spot.  We will now add movement to make the animation more realistic.  To achive this I will be changing the position of the image during the animation to give the impression that the man is running around the screen.

First we need to make sure that the image is 'absolutely' positioned on the screen by setting the 'position' CSS property of the image to 'absolute'.  This will allow us to explicitly set the X and Y co-ordinates of the top left corner of the image to the position we want.

Next we need a function that will set the direction of movement and depending on the direction, we will need to add or subtract from the x and y co-ordinates of the image. 

The 'setDirection()' function above changes the value of the 'xMultiplier' and 'yMultiplier' global variables depending on the selected direction of movement. (This function is wired to each of the directional buttons in the control panel shown in the screenshot at the top of this post.)  I can now use these multipliers to determine whether to increment or decrement the x and y co-ordinates of the image in the 'marathon()' function:


Now, whenever the marathon() method is called we first get the x and y co-ordinates of the image through the 'left' and 'top' css style attributes.  Then we add or subtract 10 pixels from these values depending on the x and y multipliers and set the new values, effectively changing the position of the image.  I also added a new array of images called 'leftRunner' to be used when the image is moving towards the left.  These images are horizontally-flipped copies of the original images used so far.  You may also notice that I'm using a 'getValue' function to get the position of the image.  This small function basically removes the "px" suffix from the value of the left and top attributes.   

Collision Detection

So far we have an animation of a man running around the screen where the speed as well as the direction of movement can be changed at any time.  We now need to add some simple collision detection to make the animation change direction whenever it hits an edge of the screen instead of running off it.


The 'collisionDetect()' function above takes the x and y co-ordinates of the animation image as parameters and determines whether the image has reached either the left, top or right edges of the screen.  It also checks whether the image has reached the bottom edge of the 'canvas' <div> which is set to 350px.  Whenever any of these boundaries is reached, the corresponding multiplier is reversed effectively changing the direction of movement.  One thing to notice here is that I used the document.body.clientWidth property to determine the position of the right edge of the screen. 

The collisionDetect() function is called from the marathon() function just before calculating the image's new position.

We now have an animation of a man running around the screen, bouncing off the edges and changing direction automatically. 

In my next post I will add the functionality to throw obstacles at the runner and look at how we can use DOM from javascript to manipulate the document.
Readmore...