Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
For 2021 - online Python 3 training - see ((here)).

Our plans were to retire in summer 2020 and see the world, but Coronavirus has lead us into a lot of lockdown programming in Python 3 and PHP 7.
We can now offer tailored online training - small groups, real tutors - works really well for groups of 4 to 14 delegates. Anywhere in the world; course language English.

Please ask about private 'maintenance' training for Python 2, Tcl, Perl, PHP, Lua, etc.
The practical solution of requirements using PHP

The "metrics" of a PHP program are very different to the metrics of applications written in languages that have been in use for many years. Most of the principles of good application design still apply, but because the environment in which they are run is so different to previous environments, we need to take a fresh look at those principles and develop appropriate techniques to ensure that we provide solutions which are
 economic to write
 easy to maintain

In this module, we'll go back and look at application design issues from first principles. If you've programmed before, please open your mind to a fresh look. If you're new to programming, be prepared to take a look at the wider issue. This module is different to our other PHP modules - we're not majoring on features of the language, rather on how we apply the language.


Why are you writing PHP? To meet a requirement. To receive, store, manipulate and provide information. How are you going to "talk" to your users? Through a web page, with data entered through forms, and results presented using HTML. How are you going to store data? Using files ... or files and directories ... or XML ... or a relational database.

Before you write one line of code, you need to have a very clear idea of just what you're going to do - a view of your application (which may turn out to be more than one PHP page) as a whole. Think first of the inputs and outputs that are to be provided. That's not only user inputs and outputs, but inputs and outputs to other systems. Also have one eye on how the requirements, inputs and outputs are liable to change in the future - you can't be a prophet, but an educated guess early on can save hours of heartache if you allow for the possibility.

Note at this early stage how we're majoring on DATA rather than on PROGRAMS. There's been a fierce argument raging in the computer programming / systems world between "structured programming" and "object oriented programming" languages, but to a very great extent OO and structured are ways of thinking rather than languages; in PHP you have tools that are designed to make the language work well for structured programmers and you have tools that are designed to make the language work well for object oriented programmers ... take your pick ;-)


We often refer to your design as a model (a model of the system). You can't see the model as a whole all at one time, but you can see a whole series of views of the model. Amongst the types of views you might see are:
 Object diagrams describing a sample of data and how it relates to other data
 class diagrams describing the structure in which data is held
 State diagrams describing how you move from one situation to another
 deployment diagrams describing what is held / runs where
 collaboration diagrams describing how parts of your system interact
 sequence diagrams describing the order of operation of parts of your model
 use case diagrams describing who makes use of what and why

For a larger project, you may wish to use a tool such as Rational's Rose to design your model, allowing changes made on screen on one view to be reflected on other view as necessary. This implies the use of a formal design system such as UML (Unified Modelling Language). For a smaller project, a less formal approach may be better.


Here's the sort of specification you'll be given:

"On our web site, each of our pages has a representative graphic on the left of the page. We would like to tell visitors why we've chosen a particular graphic if they're interested". If you're lucky, you'll be shown the current setup ... in this example, the company's webs site that they would like to add the facility on to.

What are the inputs?
 a) A request from the user for information
 b) Data about each of the images in our "graphic library"

What are the outputs?
 a) A Web page including
  - Information about the graphic
  - A copy of the graphic
  - A link back to the original page
  - An index (listing) of the graphic library
 b) [perhaps] a log file

You'll notice that the very act of writing this down has started us thinking about the requirement, and we should now go a stage further in terms of defining our data where it's we have some choice.

The "request from the user" wants to be very easy - just a link. We could choose to add a tag to our web page ("about this picture"), or we could add a link directly from the picture. Although we could provide a separate web page for each and every image, it'll be much better to provide a single script and so we're lead towards choosing a link using the GET method, with data provided as a part of the URL.

The "data about each of our images" could come in a variety of forms. We would ask our customer what form the data was available in, how much of it there was, and how (and how often) he wanted to update it. This would help us choose between options such as a directory of files, a plain text file, XML or relational database tables. PHP (the scripting language we've chosen) can handle all of these formats, and for the purpose of this example we've chosen XML - perhaps the data's already available in that format, perhaps the information provider and maintainer is familiar with it, or perhaps there are other uses that will be made of the data that suggest XML to be the preferable route.

For the outputs, what better than a sketch of the resulting web page?

Even when working on this quick sketch, we come to understand more about the application - such as thinking about how much data there will be for each image. We're concentrating on the interfacing - to and from the rest of the site, and with the user.

Having worked out our "user case", let's think about what the actual PHP script will do; in this case, it's quite easy to see that it's a single script taking the following steps:

 1. Extract titles and and text for all images from the XML source into arrays

 2. Sort the title array (what sort criteria?)

 3. Extract the title and text for the requested image from the arrays

 4. Generate the output page, filling in "the blanks" from the data we've collected
    in steps 2 and 3.

In essence, what we have there could be drawn as a flowchart or (even more formally) as a sequence diagram. Each of the flowcharts / sequence diagrams could be further subdivided, drawing a fresh diagram for the detail of each box if you wish. Or you may wish to get straight down to the coding.

Here's the code that extracts the titles (step 1)

$titles = array();
$texts = array();
$parser = xml_parser_create();
$fh = fopen('images.xml',"r");

while ($xmlcontent = fread($fh,1024)) {

And the functions called by the parser are:

function el_start($parser,$el_name,$el_attrs) {
global $imagename,$imagetitle,$imagetext,$intext;;
switch ($el_name) {
        case "IMG":
                $imagename = $el_attrs['NAME'];
                $imagetext = "";
                $intext = 1;
        case "TITLE":
                $imagetitle = $el_attrs['TEXT'];
function el_end($parser,$el_name) {
global $imagename,$imagetitle,$imagetext,$intext;
global $titles,$texts;
switch ($el_name) {
        case "IMG":
                $intext = 0;
                $titles[$imagename] = $imagetitle;
                $texts[$imagename] = $imagetext;
        case "TITLE":

function charinfo($parser,$info) {
global $imagename,$imagetext,$imagetitle,$intext;
        if ($intext) $imagetext .= $info;

You will have noticed calls to lots of functions that you may not know about if you're not personally using PHP to handle XML - just remember, PHP is excellent Glueware, and if your requirement is something that others have wanted in the past the answer will be
 "There's a function to do that ...."

Steps 2 and 3 in our sequence are very short:

$imgtitle = $titles[$_GET[img]];
$imgtext = $texts[$_GET[img]];

And step 4 comprises a number of sections of PHP spliced into the HTML; let's look at some of them. Here's how we insert the text that describes the image:

<font size="3" face="Times New Roman, Times, serif"
<?php print($imgtext); ?>
<br><br>Information in our image library is stored in XML,
which is parsed by the PHP script each time this page is
called. We'll teach you how to generate pages dynamically
from data in this way on our training courses - not only
do we train in the technology, but we use it in our own
business too!

Here's how we insert the link back to the previous page:

Link back to <a href=<?php print ($HTTP_REFERER) ; ?>>
<?php print ($HTTP_REFERER) ; ?></a>

And here's how we insert the index of all our images:

Other images in our library:<ul>
<?php foreach (array_keys($titles) as $img) {
        print ("<li><a href='?img=$img'>$titles[$img]</a><br>");
        } ?>

What does the resultant web page look like once we've written the code and clicked on the link? After the inevitable debugging, fine tuning and testing, we should come out with something that looks rather good.


The PHP environment is different to the one you'll be used to if you're not yet a web programmer.

Applications that exceed a single page chain together as a series of batchlets rather than being interactive and you have to consider
 - How to deal with user errors - re-prompting requires planning!
 - How to pass data on from one batchlet to the next

If you have a quiet site, perhaps you only have one user stepping through batchlets and a time, but you can't rely on that. You MUST use hidden fields, cookies, or URL rewrites (and - please NOT IP addresses!) to track which data belongs to which user. The session functions in PHP will usually cover most of your needs, but in order make use of them an understanding of the principles is essential. If you need to record visitors over the longer term, you can use a cookie or login system; PHP includes all the facilities you'll need, but you'll have some code to write and test.

As your site gets busier, you may have multiple active visitors at the same time ... and you might on occasions even have multiple visitors actually running your script at the same instance. Although each user process will have a separate set of variables, any files that you open are likely to be shared unless you generate their names by using a function such as uniqid.

Keeping visitors apart is vital and it's also very hard to test thoroughly. You should think through the design from first principles, provide unique file names, lock records where you need to, etc. Unfortunately, this gives rise to a further problem - abandoned files and carts.

When you visit a store, you take a trolley and return it afterwards - it would require a quite exceptional circumstance for you to abandon a trolley, half filled with groceries, in the middle of the store. Alas - this HAPPENS ALL THE TIME on web sites. Be honest - have you ever visited a web site, looked up (say) a flight fare and started to make a booking ... but then gone and bought elsewhere as you felt the price was a bit high / the timing not ideal? Yes - of course you have.

The session management functions of PHP have an expiry time set by default to 180 minutes; no activity in a session for that time, and the session expires. If you're not using session functions but doing it by hand, or if you're enhancing sessions with your own cookies / files, you'll need to provide a bookkeeper. Typically, a bookkeeper is a function which is called one time in every "n" that your PHP script is run, and it looks around a directory or table deleting items that haven't been modified for a fixed time period.

function cleancarts () {
        $dir = opendir("sessions");
        while ($file = readdir($dir)) {
                if (ereg('^\.',$file) == 0) {
                        $when = filemtime("sessions/$file");
                        if (time() - 7200 > $when) {
        closedir ($dir);


The example that we've just looked at concentrated on the overall application design - to get it working to perform as required by the specifier, rather than giving any thought to whether it will be easy to look after.

PHP is too young a language for there to be any meaningful statistics available yet, but for older languages, some 80% of code that's put into a production environment is NOT maintained throughout its life by its original author, and through the whole life cycle of a piece of software, the investment in maintaining the code is higher that in the original writing, and the investment in entering and maintaining the data is yet higher again. In other words - if you have the luxury of enough time to write your application with one eye to maintainability, you'll be making an investment with a handsome return!


Adding a comment into a piece of PHP will make no difference to how it runs, so why bother? Because it will make a difference to how you (be you the author or the maintainer) can read the code later.

Suggestions for commenting which you might like to make your standard:
 - Comment each function with a description of inputs, outputs and task performed
 - Comment every logical block of code (blocks of 20 or 30 lines) to overview tasks
 - Add extra comments where you do something "clever". "Clever" is often another
   word for "obscure"
 - In large blocks of code or if you have persistant data, describe the data structures
 - If you have complex structures and references, describe them
 - Include same lines from your data files or database records within your program
 - Include a header block with pertinent data in each file.

Even white space is a form of comment. Inset your blocks so that it's very clear where one block starts and another ends.

Remember that comments within the PHP section of your file do NOT cost bandwidth, and are NOT visible to your site visitor. They are there purely for you and your successors. It is vital that your PHP also provides user documentation so that the user of your pages knows how to get the best from them - what's the point in writing something really clever if no-one ever stumbles across it?

HTML is tailor made for user instructions in PHP! It's a text mark-up language after all! Don't just put boxes into your application, describe them! Think of adding "info" or "help" buttons too that link to other pages ... you might not have to maintain large numbers of other pages even if you provide a lot of information - you could use a standard scheme like we used for out images (see earlier in this module), and then you've just got text or XML files to maintain.


A huge gain that can be made from good coding is code re-usability. If you get it right, you can write a piece of code once and call it up from tens or hundreds of places - and if a change is needed later, you have one change and not those tens or hundreds. But there's even more to it than than. If you have re-usable code (and you do use it), you're providing something that's more consistent for your site visitor or data provider; you save them time and give them comfort from doing this.

When you first start writing PHP, you'll be so busy trying to get your application to work that functions will be the last thing on your mind but early on ...
 - Write code from "the top down", as a series of function calls from the start
 - Split out code that performs a single logical task into functions.
 - group together functions that deal with a particular type of data
Even at this early stage, you'll find that testing is aided as you can cleanly test your coding function by function and build more reliable code more quickly.

As soon as it's clear that you've got a group of functions that's useful to more that just a single script, you should earmark them for placement in an include file - even though you may leave it in the current file while you're developing to avoid having just too many edit windows open at the same time!

In PHP, you can include files with the following functions:
 include load multiple times if called multiple times, warn if include fails
 include_once load once even if called multiple times, warn if it fails
 require load multiple times if called multiple times, fatal error if require fails
 require_once load once even if called multiple times, fatal error if it fails

Include files are so powerful; almost everyone uses them - not only to include functions, but also for "boiler plates" in HTML ...

BEFORE you start writing a new file of functions, ask yourself if someone in your organisation might have written just what you need already - this module is about writing good code, but the very best solution may simply be not to write code! Where can you look for functions?

 - In your own earlier work
 - In your colleague's work
 - On the Internet (have a look at pear.php.net)
 - In the standard PHP library

PEAR is short for "PHP Extension and Application Repository" and is pronounced just like the fruit. The purpose of PEAR is to provide:
 - A structured library of open-sourced code for PHP users
 - A system for code distribution and package maintenance
 - A standard style for code written in PHP
 - The PHP Foundation Classes (PFC)
 - The PHP Extension Code Library (PECL)
 - A web site, mailing lists and download mirrors to support the PHP/PEAR community


There are two issues here - versions of your program, and versions of the environment in which you're using your program.

With your own code, we recommend a version numbering system so that you can tell whether a piece of code is current or not - especially important if you're distributing you code to others. If there's a group of you working on a PHP program, we suggest that you consider using a source code and version control system such as CVS, SCCS or RCS; it's a pain having to check code out and in again, but it does prevent several people working on the same file at the same time and destroying each other's changes, or giving resynchronisation problems.

New versions of files of functions or objects that you distribute for use with include or require should remain compatible with older versions. This means that the interface you provide mustn't have anything removed, or altered in how it performs if it's called in the historic way. You can add extra functions to provide extra functionality, you can add optional extra parameters onto functions, and you can add further keys that have special significance to arrays that you let your users pass in to you.

In PHP, the environment is a "tricky one". You can't just write a piece of PHP and know that it will automatically work on any computer that has PHP installed. Issues include:
 - Operating system issues
 - PHP version issues
 - PHP configuration issues
 - Web server configuration issues
 - Module availability issues
 - Relational database and other service availability.

Web server configuration issues relate to matters such as what extension should you apply to your PHP files, and whether you have to use <?php or can use the shorted <? format in your code. If you want to access data files outside the document tree on the web server, that's another issue that will depend on how the system administrator installed and configured the system software. How environment variable and sessions directories are configure in the php.ini file ...

Graphics modules, xslt support, Pspell functions, shared memory functions. Just a few of the modules which might be on your development system, but may not be provided by your production server's admins!

Even the business of collecting variables from forms differs - and there's not one single way we can tell you to write code with the assurance "this will always work" ... not even if you limit yourself to PHP4.

Once you're comfortable with the fundamentals of PHP, consider carefully how you're going to code - what versions of PHP your code will run under, any mandatory configuration issues, etc. If you're using a development server, much better if it can be similar to your production machine - or if it can be limited to a minimum set of facilities if you're writing code for wider distribution.


If you look at Pear, you'll find a suggested set of standards for coding:

Indenting and commenting of code, using include files, etc. are all good ideas. You may wish to use further coding standards too - we can't fault consistency, but it really doesn't matter whether on not you leave spaces before and/or after the commas in function parameter lists.

Variable names should be long enough to give an indication of their meaning, and short enough to avoid the need for too much typing. As you start naming elements that have a wider use, you should set (or stick to) some wider rules. For example:

 Global variables should have names starting with an _ ... so:

 Functions should have names starting with their grouping or package name
 followed by an _ .... so:
  ncsa_readLogFile(); ncsa_recordValidate();
 (and note we've capitalised the embedded word starts).


You're writing a file of PHP. What does it contain?
 - PHP
 - HTML tags (probably)
 - SQL (possibly)
 - JavaScript (maybe)
 - XML (maybe)
 - English, French or Spanish text

So it follows that you need to know all those languages in order to write the file, and to be able to maintain it. And you need to use exactly the right format in each language of your application will fail in some way (worst case), or just look plain bad to the user.

A first suggestion for clarity - try to avoid too much switching in and out of PHP mode; try to write each of the sections of code in substantial blocks. There's nothing to stop you "striping" your code to the extent that every line seems to switch from PHP to HTML or vice versa ... but don't do it - maintenance nightmare!
  <?php } ?>><?php else { ><<?php ....
will probably work, but I don't fancy taking over your code and supporting it!

You can use much bolder stripes. Write your code at the top of your PHP file - handle your inputs, do all your calculations, save anything that you need back to disc .... THEN generate your HTML with just occasional jumps into PHP mode for echoes or prints! Not only does the code look much cleaner, but you can be sure that if your user gets bored while he's receiving your page and he hits the stop button on his browser, he won't leave disc files half written. (note - depending on how PHP is configured, it may automatically buffer all output anyway).

Chances are that you have just a few PHP experts, and just a few Graphic Designers who are familiar with HTML or tools such as Frontpage or DreamWeaver. Alas, they're unlikely to be the same few people, so if the whole responsibility for a PHP page rests with one person it will either work and look "Naff", or it will be beautiful but won't function.

We suggest you consider using the following scheme:
 - Get a sample HTML page written by your Graphic specialist
 - Add your own extra markups (call it HTML++ if you like!) which indicate
  fields to be completed.
 - In your PHP code, read in the HTML page as a template and use regular
  expression substitution to complete the variable parts.

Here's some code from a contract we undertook:

function filltemplate ($template,$fields) {
 global $errstr;

/* Reads a template from a file named in $template and fills in
the template using tags of the form %\w+% to identify elements
of the associative array $fields to be used for completion */

        if (file_exists($template)) {
                $fh = fopen($template,"r");
                $content = fread($fh,filesize($template));
        } else {
                $errstr .= "<BR>Error 1505 - Error Page Missing";
  $content = "Error Page";

        foreach (array_keys($fields) as $fill) {
   return ($content);


Different relational database products offer varying facilities, yet you want to write code that will work across platform. Language authors have a choice of two ways that they can support a database - either they can support a wide range of features (in which case they have a portability issue), or they can support just a common subset of features (in which case their users won't be able to get at the extra power is they want to). Hobson's choice - neither is ideal.

PHP supports a wide range of features of each database, and provides a different set of functions to support each. This means that if you write code that calls these functions, your code will not easily port to another relational database.

At least having made that choice in PHP, YOU (the programmer) can choose to write code that's going to be portable by using a wrapper. This works as follows ....
 - you call a function which is database independent in its calling sequence
 - different versions of that function are provided, and depending on which you
  include, you'll have a version that calls a different database product.

The ADOdb package is available for download, and it provides a full set of wrappers for databases; it's also straightforward to write your own, and there's listings of examples for the commoner databases in "PHP Developer's Cookbook" - see http://www.wellho.net/book/0-672-31924-1.html

If you're looking to write portable code, we suggest that you start with writing / testing with MySQL. It's fast, it doesn't usually require a license payment, and if MySQL can do something, most of the other databases can too.

Here are some sample functions from a wrapper that we use ...

function opendb($host,$database,$user,$password) {
        global $errstr;
        if (! ($dbid = mysql_connect($host,$user,$password))){
                $errstr = "Error 1501".
   " - SQL server $host unavailable";
                $retcode = 0;
        } else {
                if (! mysql_select_db($database,$dbid)) {
                        $errstr = "Error 1502".
   " - No database $database";
                        $retcode = 0;
                $retcode = $dbid;
        return ($retcode);
function runsql($dbid,$query) {
        return (mysql_query($query,$dbid));
function fetchrecord($result) {
        $record = mysql_fetch_assoc($result);
        return $record;


Use variables - just define values once. Put directory paths, server names, etc. into variables in a header file so that they can easily be changed. Never hard code a tax rate ;-)


Up to this point, we've been considering writing code that's follow-able and maintainable - but what better than to see if we can get the design right and make it robust too so that there's only a minimum of maintenance required?

Code that you write for "one off" use need only function on the data set for which it's intended. More care needs taken in multiple data sets are to be used, and yet more care if the code is to be run on a number of potentially different systems or by unfriendly users - military programmers call this latter "squaddie proofing".

In general, it's best to write data interpretation from first principles. For computer data formats that may take a little time, but in theory at any rate it should always be possible if you have a data specification. For human edited formats, it's very hard to get it right from first principles every time - consider how you make a word into a plural in English:
  cow cows
  pig pigs
  sheep sheep
  child children
  die dice
Unless you invest in developing a large "special case" library, there will always be a few oddities.


Enter "John Smith" onto a web page, save his name in a relational database, call it back and display his name in a table of employees and all will work fine. Then enter "Brendan O'Toole" and see a screen full of error messages, or enter "Paul <br> Jones" and see your format go all askew.

Although you can hold any characters in a variable in PHP, there are special considerations:
 - when you read from a form (URL encoding - special use of %xx)
 - when you save to a database (\ protection)
 - when you echo to a web page (problems with & < " and ')

Use functions such as strspn to check incoming data for characters that you're simply going to refuse to handle, and then (thinking from first principles as you code) use addslashes, stripslashes and htmlspcialchars (or the alternatives) as you use PHP to glue the web and database together.

For checking above the character level, remember the power of regular expressions, and remember that most users don't know the difference between a space and a tab, and between a capital and a lower case letter. Remember accented characters too!


If a function returns a status, check the status (if your SURE you don't need to, remember that you can precede the call with @). If has always opened successfully every time since you wrote your program - still check it. Even if you're told you can trust the format of a data file, don't. One day, a human editor might put in two spaces where you assumed just one. Remember
 "assume" makes an ASS out of U and ME ...........

With network programming, checking is all the more vital. Your SQL server computer may go down. It may be inaccessible via the net. Do you check for this? You should!

It's quite reasonable in some circumstances for a piece of PHP code to be 90% checking and only 10% action.


What will you do if something goes wrong? Best provide an error message. Best make it descriptive too. Ever run someone else's software that just says "program Failed" ... not helpful :-( ...

It's worth giving a good error message (and perhaps a link to further information - this is really user documentation that we covered earlier in this module). If the error is data relates, it's worth echoing the data with fault and indication where the problem is. Which to you prefer:
 "Part numbers much not exceed 4 characters"
 "Error 1764 - Part numbers must not exceed 4 characters.
  File demo.txt, line 55 - 'AC542' too long"
The number of error is a great help too if you're going to provide a list for people - and it helps too if people are going to phone or email in for support - you can ask them for the number and be assured that you then know exactly which error it was

See also Training on Best Practice - PHP application design

Please note that articles in this section of our web site were current and correct to the best of our ability when published, but by the nature of our business may go out of date quite quickly. The quoting of a price, contract term or any other information in this area of our website is NOT an offer to supply now on those terms - please check back via our main web site

Related Material

Designing PHP-Based Solutions: Best Practice
  [123] - ()
  [237] - ()
  [261] - ()
  [340] - ()
  [394] - ()
  [426] - ()
  [563] - ()
  [572] - ()
  [839] - ()
  [896] - ()
  [936] - ()
  [945] - ()
  [1047] - ()
  [1052] - ()
  [1166] - ()
  [1181] - ()
  [1182] - ()
  [1194] - ()
  [1321] - ()
  [1323] - ()
  [1381] - ()
  [1389] - ()
  [1390] - ()
  [1391] - ()
  [1482] - ()
  [1487] - ()
  [1490] - ()
  [1533] - ()
  [1623] - ()
  [1694] - ()
  [1794] - ()
  [2199] - ()
  [2221] - ()
  [2430] - ()
  [2679] - ()
  [3539] - ()
  [3813] - ()
  [3820] - ()
  [3926] - ()
  [4069] - ()
  [4118] - ()
  [4326] - ()
  [4641] - ()
  [4691] - ()

resource index - PHP
Solutions centre home page

You'll find shorter technical items at The Horse's Mouth and delegate's questions answered at the Opentalk forum.

At Well House Consultants, we provide training courses on subjects such as Ruby, Lua, Perl, Python, Linux, C, C++, Tcl/Tk, Tomcat, PHP and MySQL. We're asked (and answer) many questions, and answers to those which are of general interest are published in this area of our site.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2022: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho

PAGE: http://www.wellho.net/solutions/php-the- ... g-php.html • PAGE BUILT: Wed Mar 28 07:47:11 2012 • BUILD SYSTEM: wizard