Tuesday, October 31, 2006

Chameleon Coding


Introduction
A chameleon is a lizard that is well known for its ability to change skin color. This is a useful metaphor for web programming as it highlights the importance of separating well structured and stable backend code from the dynamic web pages it supports.
PHP is the perfect language for chameleon coding as it supports both structured classes and simple web scripting. In this section we will look at some coding and page structures you can use to help build applications that are robust, yet easy to change and simple to maintain.

Code Structure
When writing PHP code we need to make a clear distinction between the code which does the principal work of the application and the code which is used to display that work to the user. The backend code does the difficult tasks like talking to the database, logging, and performing calculations. The pages that display the interface to these operations are part of the front end.
Mixing programming code in with HTML is messy. We can talk about ways to format the code or structure your pages, but the end result will still be quite complicated. We need to move as much of the code away from the HTML as possible. But, we need to do this so that we don't get lost in the interaction between our application and the user interface. A web site is a dynamic target. It is continually evolving, improving and changing. We need to keep our HTML pages simple so that these changes can be made quickly and easily. The best way to do that is by making all calls to PHP code simple and their results obvious. We shouldn't worry too much about the structure of the PHP code contained in the front end, it will change soon anyway. That means that we need to remove all structured code from the actual pages into the supporting include files. All common operations should be encapsulated into functions contained in the backend.
In complete contrast to the web pages your backend code should be well designed, documented and structured. All the time you invest here is well spent, next time you need a page quickly hacked together all the hard parts will be already done waiting for you in backend functions. Your backend code should be arranged into a set of include files. These should be either included dynamically when required, or automatically included in all pages through the use of the php_auto_prepend_file directive. If you need to include HTML in your backend code it should be as generic as possible. All presentation and layout should really be contained in the front end code. Exceptions to this rule are obvious when they arise, for example, the creation of select boxes for a date selection form. PHP is flexible enough to let you design your code using classes and or functions. My object oriented background means that I like to create a class to represent each facet of the application. All database queries are encapsulated in these classes, hidden from the front end pages completely. This helps by keeping all database code in a single location and simplifying the PHP code contained in pages.

Include File Structures
Include files are a PHP hackers best friend. Use them liberally to help you layout and control your code. The performance drop due to extra include files is completely insignificant next to the gains you will get from ease of maintenance and better understanding of your own code.
A good example use of include files is to separate out sections of content into a form that makes them easier to maintain and reuse. For example, many home pages on the web are basically broken into a number of content boxes. Yahoo is basically boxes of links, auctions, news, shopping, events and self-promotion. Using include files in PHP we can break this page into the following structure: index.phtml
-> links.inc
-> auctions.inc
-> news.inc
-> shopping.inc
-> events.inc
Now each content box is on its own and can be maintained independently. This structure is so simple that you can use it to build completely dynamic sites for people who know nothing about PHP and refuse to use any HTML editor other than Frontpage. Just break their content areas out into a number of small files and let them go nuts. Your PHP code is safely locked in files called something like index-dont-touch.php that they can ignore.
Best of all, those content boxes can be reused anywhere on the site and only need to be edited and updated in a single location.

Form Structures
Another essential structural element in all web applications are user forms. These little beasts seem so simple but are so important that we have to get them completely right. The easiest way is to develop some standard PHP structures for handling forms that we can copy and paste over and over again.
The easiest way to do web forms is through a multiple page interaction with the user. The simple case is just to have a page for prompting and a page for processing the results. Slightly more complicated (mostly due to the urlencoding problems discussed above) is to add a confirm step to the sequence. Here is a file structure that we found to be fairly flexible across many applications:
index.phtml - prompts the user
check.inc - checks the data inputs from both the confirm and save pages
confirm.phtml - shows the data back to the user letting them confirm it is correct
save.phtml - processes the data and prints a success message The problems inherit with this method are that you rely quite strongly on the browser back button (which for some strange reason many users have difficulty finding) and the confirm step can be annoying for simple operations but is not easy to bypass. It is also a problem to leave the user looking at a save page that they can potentially reload adding duplicate data or getting database errors.
A more flexible and robust scheme that we've been working on lately uses a more complex include file structure but manages to break up all the form processing steps into simple stages. This makes it simple to write forms and the end result is easier to use. All of the prompting, confirming and saving phases are done on the same page. This way we can display errors along with the data to be edited, can make the confirm step optional for the user, and can redirect from the save step to another location.
index.phtml - the main control script for working through the sub-scripts below
prepare.inc - prepare the data by urldecoding etc if necessary
cancel.inc - redirect the user to a sensible location if they cancel the entire operation
check.inc - check the data that has been entered and construct any relevant error messages
init.inc - get ready to display the prompt page by looking up or processing data
index.inc - display errors and prompt the user for input
confirm.inc - display the entered data and prompt the user to confirm, cancel or go back
process.inc - perform any processing that needs to be done before the save script is run
save.inc - perform the actual operation and redirect to a sensible location (eg: view page) Unfortunately there are many files to edit, which can be annoying. The redirection upon cancel or save can be a problem depending on the quality of the data given to the form. These pages rely on the urlencoded state for each variable being set. Using a urlencoded state gives us a lot of power and flexibility but can increase the burden on the programmer who is trying to interface with our forms. Fortunately, at worst they are no worse off than we were already for dealing with urlencoding of variables.
Here is the structure for the index.phtml file calling to the other scripts: include('./prepare.inc');
if (isset($cancel)) {
include('./cancel.inc');
}
else {
if (!isset($confirm) && !isset($save)) {
include('./init.inc');
include('./index.inc');
}
else {
include('./check.inc');
if (!strempty($error_message)) {
include('./index.inc');
}
else {
if (isset($confirm)) {
include('./confirm.inc');
}
elseif (isset($save)) {
include('./process.inc');
include('./save.inc');
include('./cancel.inc');
}
}
}
}

0 Comments:

Post a Comment

<< Home