Last week we continued the tutorial on Unobtrusive AJAX Navigation by cleaning up our Javascript code as well as adding functionality which enabled users to bookmark individual pages and use the “Back” and “Forward” browser buttons for navigation. This time, we’ll focus on cleaning up the back-end scripts to make the solution easily maintainable and expandable. Check out the fully functional demo and/or download the files for this tutorial.
There are two equally good approaches to achieve our goal. One is using simple server-side include (SSI) instructions to keep common content in separate files and include them into our pages at the time when it is needed. The second approach is via Object Oriented (OO) PHP. I am a big fan of OO but too often I see it misused by self-pronounced programmers who naively think that throwing OO concepts on everything makes them better coders (nothing could be further from the truth). There is place and time for deciding to “complicate” your file structure but unless you’re about to create a solution of the size of WordPress (for example) you should think really hard about the pro’s and con’s. Unless your intention is to build a robust, easily extendable and maintainable product with support for hundreds of thousands of users, good old procedural scripting will do the job just as well (if not better).
So without much further ado, let us look at the back-end code from the previous projects:
The first thing that is immediately obvious is that the majority of code in “index.php” and “about.php” is identical. Let’s split this code into appropriate files. Create a directory called “inc” and place the following “.htaccess” file in it:
Order Allow,Deny
Deny From AllAll this file does is it prevents any sort of (GET, POST, HEAD etc) requests made directly to the /inc directory. Next, we create a file called “header.php” and place the “print_header” function in it:
<?php function print_header(){ ?> ... <body id="version-1-0"> <!-- WRAPPER - START --> <div id="wrapper"> <!-- HEADER - START --> <div id="header"> <h2>Unobtrusive Ajax Navigation - Version 3.0</h2> <ul > <li><a href="index.php">Home</a></li> <li><a href="about.php">About</a></li> </ul> <div></div> </div> <!-- HEADER - END --> <!-- CONTENT - START --> <div id="content"> <?php } ?>
Similarly, we create “footer.php” and place the “print_footer” function code in it.
<?php function print_footer(){ ?> </div> <!-- CONTENT - END --> <!-- FOOTER - START --> <div id="footer"> <p>Footer</p> </div> <!-- FOOTER - END --> </div> </body> </html> <?php } ?>
Then create another two include files, one for the content of “index.php” and one for the content of “about.php”. Let’s name them “index.inc.php” and “about.inc.php” respectively, and place the “print_content” functions in them, like so
<?php function print_content(){ ?> <h2>Homepage</h2> <p>Lorem ipsum ...</p> <?php } ?>
<?php function print_content(){ ?> <h2>About</h2> <p>Lorem ipsum ...</p> <?php } ?>
Next, create “content.php” and place the code from above the “print_header” function in “index.php” (or about.php) into a newly created “print_page” function, like so
function print_page( $page ){ require_once("inc/header.php"); require_once("inc/footer.php"); require_once( $page ); // if the page is requested by AJAX if ( isset($_REQUEST['ajax']) && $_REQUEST['ajax'] == "true" ){ print_content(); } else { print_header(); print_content(); print_footer(); } }
Perhaps, this new function requires a bit of explaining: We want to remove all (as much as possible) code duplicity, so create a function which will print a page content, just as we did before (depending on whether the request came directly from a browser or was requesting by our AJAX Javascript code). The only difference is that we use the “$page” argument to tell the function which page needs to be printed. The script will use the “print_content” function from the appropriate file.
Now, whenever you see something resembling
require_once( $content_inc );
your red alert flashing light should immediately go off. This is potentially a huge security risk: if someone could make the value of “$page” to be “.htaccess” or “.htpasswd” the user could read (encrypted) passwords and see other site settings. In the particular use of the construct, it is unlikely (nothing is impossible) that anyone would be able to exploit it. Nevertheless, it is possible that sometime in the future, to extend functionality or for some other purpose, the smallest modification to the code could leave us vulnerable against an attack. In short, the best practice is NEVER to trust the user, especially when a potential security flaw can easily be fixed by restricting the possible value set. Add the following lines before the function declaration:
define("PAGE_HOME", 0); define("PAGE_ABOUT", 1); define("PAGE_HOME_SSI", "home.inc.php"); define("PAGE_ABOUT_SSI", "about.inc.php");
change the function declaration to
function print_page( $page = PAGE_HOME )
and add the following switch statement:
switch( $page ){ case PAGE_ABOUT : { require_once( PAGE_ABOUT_SSI ); break; } case PAGE_HOME : { // fall through to default } default : { require_once( PAGE_HOME_SSI ); break; } }
The few extra lines of code is all that is necessary to prevent the possibility of a large headache (at best) in the future.
Now, all that’s left is to use the newly created files and functions in our original scripts. Thus, we go to “index.php” and place the following lines of code in it:
<?php require_once("inc/content.php"); print_page( PAGE_HOME ); ?>
Similarly, in “about.php”
<?php require_once("inc/content.php"); print_page( PAGE_ABOUT ); ?>
We will conclude this tutorial by adding a page called “Contact”. First of all, create a “contact.php” in the main folder and place the following code inside it:
<?php require_once("inc/content.php"); print_page( PAGE_CONTACT ); ?>
Then open the “content.php” inside the “inc” folder and add
define("PAGE_CONTACT", 2); define("PAGE_CONTACT_SSI", "contact.inc.php");
as well as
case PAGE_CONTACT: { require_once( PAGE_CONTACT_SSI ); break; }
into the switch statement. Then, let’s add the Contact Page to our navigation by placing the following into the “header.php”
<li><a class="ajax-link" href="contact.php">Contact</a></li>
Finally, we need to create a “contact.inc.php” inside the “inc” directory with a “print_content” function:
<?php function print_content(){ ?> <h2>Contact</h2> <p>Address Line 1</p> <p>Address Line 2</p> <p>City, Zip Code</p> <p><strong>Country</strong></p> <?php } ?>
Next time, we will look at creating Unobtrusive AJAX Navigation as a part of a complex product (using OO) as well as making URL more user friendly (although search engine are perfectly capable of indexing links with query parameters there is an elegant way to make links more user friendly).
Meanwhile, check out a fully functional demo of version 3 and/or download the files for this tutorial.

