Skip to content Deakin home Contact Deakin Directory of staff Site map A-Z index Help Portal
Applications Unit
Information Technology Services Division
Decrease text size Increase text size print
Deakin home > Information Technology Services Division > Applications Unit

Best practices guidelines for web development using PHP and Oracle (draft)

Introduction

This document outlines what is considered to be some best practices when writing PHP code. It does not pretend to be a definitive guide for coding standards but is merely just a helping hand for those starting out.

Development tools

It doesn't particularly matter if you use notepad and sqlplus to undertake web development as you should be able to use your preferred tools of choice to get the job done. However you may find yourself more productive if you use a dedicated GUI editor. Currently Macromedia Dreamweaver is licensed for Deakin University and can be installed via the Phoenix software catalogue. Other popular development tools for PHP include

Obviously there are many more out there feel free to pick whatever you are comfortable with, if you like VI then go for it.

Accessibility

Even though this guide is supposed to be about PHP it is likely your code will be outputting HTML at some stage and therefore accessibility is an important factor to consider. This is especially true considering the University has policies relating to it. Without duplicating the various documentation here I will point you to where you can find all the relevant information pertaining to creating accessible webpages within Deakin.

Breaking in and out of PHP

For pages which contain both PHP and HTML it is advised to break in and out where required to improve readability and performance. Using echo throughout PHP to generate your HTML is NOT recommended. For large blocks of PHP code it is advised to use the <?php ?> tags. This has two advantages over the shorthand version <?, they are:

  1. it won't cause problems with XML.
  2. doesn't require short_open_tag to be enabled in the php.ini configuration file

Having said this I still believe that the third version of the shortcut tag <?= can keep your code looking a lot neater when you are required to break in and out of PHP numerous times in a segment of HTML code. Some examples below.

1) Bad example
<?php
$arrayFruit = array('banana' => 2, 'apple' => 1, 'orange' => 4);
echo "<table>";
echo "<tr>"; echo "<td>$arrayFruit['banana']</td>";
echo "<td>$arrayFruit['apple']</td>"; echo "<td>$arrayFruit['orange']</td>";
echo "</tr>";
echo "</table>"; ?> 2) Bad example <?php $arrayFruit = array('banana' => 2, 'apple' => 1, 'orange' => 4); $html = "<table>
<tr> <td>$arrayFruit['banana']</td>
<td>$arrayFruit['apple']</td> <td>$arrayFruit['orange']</td>
</tr>
</table>"; echo $html; ?> 3) Good example <?php $arrayFruit = array('banana' => 2, 'apple' => 1, 'orange' => 4); ?> <table>
<tr> <td><?=$arrayFruit['banana'] ?></td>
<td><?=$arrayFruit['apple'] ?></td> <td><?=$arrayFruit['orange'] ?></td>
</tr>
</table> 4) Another good example <?php $arrayFruit = array('banana' => 2, 'apple' => 1, 'orange' => 4); ?> <table>
<tr> <td><?php echo $arrayFruit['banana'] ?></td>
<td><?php echo $arrayFruit['apple'] ?></td> <td><?php echo $arrayFruit['orange'] ?></td>
</tr>
</table>

 

In good example no. 3 the <?= tag is a shortcut for using <?php echo on each line. Regardless of this convenience if you intend to develop portable applications or libraries especially those destined for servers not under your control do not use short tags. This is spelt out in the PHP documentation at http://www.php.net/manual/en/language.basic-syntax.php

Note: There is actually a bug in example 1 and 2 that would cause a parse error. Enter the special character which you could use overcome this (not that you would use these bad exmaples anyway) and win a free banana!

Using single and double quotes

The use of quotes in PHP is often misused and can cause performance issues in large blocks of code if not used appropriately. The following example illustrates a simple variable declaration and when double quotes should be used versus single quotes.

$name = "Bill";

That isn't efficient; the whole point of double quotes is to allow interpolation. Meaning, PHP checks anything within double quotes for a variable. Like so:

echo "My name is $name";

Therefore in order to save the PHP parser from going through the string "Bill" looking for a variable you should use single quotes where appropriate. eg

$name = 'Bill'; 

This not only applies to strings but everything eg function calls

$str = str_replace('Cat', 'World', 'Hello Cat');
$conn = OCILogon('username','password', 'db_name');

Taken from http://www.devarticles.com/c/a/PHP/Some-PHP-Guidelines-to-Live-By/1/

Using quotes for array indexes

Static text indices to arrays should always be in single quotes. For example,

$id = $_POST[‘id’]; 

not

$id = $_POST[id]; 

In the second line PHP tries to match a constant called id, then, if it can’t, looks assumes you mean the string ‘id.’ Not only could this cause problems if you happen to have a constant called id defined, but it also results in unnecessary processing.

Complex syntax

For circumstances where you want to reference an array element inside a double quoted string such as an SQL insert statement you can use what is called 'complex syntax'. This can be achieved by simply surrounding the expression with curly braces. In this case an element of the $_POST array.

$sql = "insert into MY_TABLE (name, age,) values ({$_POST['name']}, {$_POST['age']})";

Using curly braces around the variable as above or alternatively closing the quotes and appending the variable to the string would be the correct to do this. eg

$sql = 'insert ... ' . $_POST['id'] . '...';

Do NOT reference the array element without the text array index quoted

$sql = "insert into MY_TABLE (name, age, emp_no) values ($_POST[name], $_POST[age])";

You would not do this for the same reason as explained in the above section because PHP would try and match that constant name first.

 

No magic numbers

A magic number is a bare-naked number used in source code. It's magic because no-one has a clue what it means including the author inside 3 months. For example:

if      (22 == $foo) { start_thermo_nuclear_war(); }
else if (19 == $foo) { refund_lotso_money(); }
else if (16 == $foo) { infinite_loop(); }
else                 { cry_cause_im_lost(); }
In the above example what do 22 and 19 mean? If there was a number change or the numbers were just plain wrong how would you know?

Heavy use of magic numbers marks a programmer as an amateur more than anything else. Such a programmer has never worked in a team environment or has had to maintain code or they would never do such a thing.

Instead of magic numbers use a real name that means something. You should use define(). For example:

define("PRESIDENT_WENT_CRAZY", "22");
define("WE_GOOFED", "19");
define("THEY_DIDNT_PAY", "16");

if      (PRESIDENT_WENT_CRAZY == $foo) { start_thermo_nuclear_war(); }
else if (WE_GOOFED            == $foo) { refund_lotso_money(); }
else if (THEY_DIDNT_PAY       == $foo) { infinite_loop(); }
else                                   { happy_days_i_know_why_im_here(); }

Echo versus Print

The ‘echo’ statement and ‘print’ function are essentially the same however there is a small difference between the two . The ‘print()’ function behaves like a function in that you can do:

$ret = print ‘Hello World’; 

And $ret will be 1

That means that print can be used as part of a more complex expression where echo cannot. The ‘print()’ function is also part of the precedence table which it needs to be if it is to be used within a complex expression. For example consider the following:

// Because echo is not a function, following code is invalid. 
( $some_var ) ? echo 'true' : echo 'false' ;

// However, the following examples will work:
( $some_var ) ? print( 'true' ): print( 'false' ); // print is a function
// changing the statement around will work 
echo $some_var ? 'true' : 'false' ; ?> 

Since the ‘echo’ statement doesn’t return a value and is marginally faster, it is recommended that it be used instead of print where possible.

Session and Cookies

The following should be considered when using sessions and cookies.

Do not use session_register() and session_deregister() Always use session_start() at the top of the PHP file when using sessions

The following example illustrates that sessions in PHP perform a lot better with register_globals off.

Examples:

$username = $_POST['uname']; session_register('username'); 

PHP needs to know that the above variable is being registered as a session variable

$_SESSION['username'] = $_POST['uname'];

In this example we are using the $_SESSION array. When this is used PHP is aware that if something is stored in this array that it is a session variable so there is no need to register it.
The username session variable can be unset by using the following:

unset($_SESSION['username']); 

 

Code comments

It is strongly recommended that you use phpDocumentor style comment tags to document your PHP code. This special comment syntax allows the parser to generate documentation automatically. For more information about how to use phpDocumentor visit http://www.phpdoc.org/

phpDocumentor is intalled at http://www.deakin.edu.au/its/phpDocumentor/

-->

Coding standards

Please adhere to the various application standards available at www.deakin.edu.au/its/apps/doco/standards/

Interacting with Oracle from PHP

The use of common functions when interacting with an oracle database is always recommended. Some basic function calls that should be used are as follows:

In addition to the above some good coding practices should be adhered to.

When connecting to a database the connection should be closed early as possible. An easy way of doing this is to fetch all data and store it in variables before displaying anything (which also means you're half way to using a three-tier model).

Following this technique achieves three things:

If following a well-established programming methodology (i.e. three-tier), separating presentation from data, and increasing maintainability isn't enough. Then the last point is even more advantageous as it means that (under normal circumstances) the user doesn't get half the page displayed then has to wait for the rest. All the lag time will happen before they see the page start to render, and hence will assume that the lag is just a normal part of the web and not something to do with your application.

A possible disadvantage of doing this would be if there is a lot of data processing to perform. The user may be left with a blank page wondering why they haven’t received any feedback. Giving the user a temporary page informing that the request is being processed can avoid this situation.

Referencing database fields should always use the column names and not the number of the column. For example, don't use $value = ociresult($call, 1); use $value = ociresult($call, 'ID'); The latter method is much more descriptive and easier to understand than the former. Note that column names must be uppercase for oci* calls as this is how they are returned.

Note the PEAR DB :: Class can also be used instead of generic OCI functions for database connectivity as this abstracts the database connection.

Error handling

HTTP Errors

The site must handle HTTP Errors and display appropriate information when errors occur. Currently HTTP errors are handled by the default Deakin error pages and where possible it is recommended that errors be allowed to fall through to these pages. In instances where the application is not being developed on the main University web server there may be a need to set up your own custom error pages this can be controlled via the .htaccess file and is explained below.

Custom error documents can be created to display in response to errors such as requests to non-existent files, by using the ErrorDocument directive. Never declare a URL as the destination for the ErrorDocument. Always set the location to the absolute or relative path of the file, as demonstrated below.

ErrorDocument 404 errors/notfound.html
ErrorDocument 403 errors/forbidden.html
ErrorDocument 500 errors/servererror.html

Some common error messages are listed below:

Oracle and PHP errors

Errors should be logged to an appropriate log table with an error code/message being returned from the database to the calling PHP page so as an appropriate message can be displayed to the user. It is important that all error messages are concise but descriptive so that users are not confused as to why an error has occurred. It is recommended that you trap your database errors from PHP and use OCIError function call or the PEAR equivalent to display them. If you are using OCIError or similar to display your errors any raw errors from OCI function calls should be supressed using the @ symbol in front of the function call or by setting the error reporting level using the function error_reporting(). If display_errors is set to off in php.ini neither is required. When ouputing an error msg in a log file or to the screen use the PHP __LINE__ constant to show what line in the code where the error occured. eg

if(($return = mail($to, $subject, $body)) === FALSE){
	doError('Email could not be sent', __LINE__);

}

HTML forms

When creating a form the following points should be followed:

Form validation

Forms are to be validated using JavaScript functions. Where possible always use server side validation as this minimises the risk of clients having JavaScript disabled and having to support multiple browser platforms. Some common validations are as follows:

Security and Auditing

PHP security

Security considerations that should be taken into account before undertaking development http://phpsec.org/projects/guide/

Database security

Database security considerations are covered in more detail in the Oracle coding standards. In short:

Writing to file

PHP_EOL

When reading the contents of a file or writing to one its important to note that each line ends in a series of characters that defines the end of the line. These end of line characters differ depending on the system.

PHP has an inbuilt constant called PHP_EOL which will be converted to \n or \r\n depending on the system. So rather than hardcoding an end of line character let PHP do the thinking and use PHP_EOL.

Eg: $currentline = rtrim($line, PHP_EOL);
    $newline = $currentline . 'new text' . PHP_EOL;

Images

The following should be abided by when incorporating images into your code.

Javascript code

Where possible restrict the use of JavaScript within the <head> and </head> tags however it can be used outside these tags if necessary. JavaScript can be used for error handling, validation, to instigate pop-up boxes and should always be used with the ‘language’ and ‘type’ attributes:

<script language=”JavaScript” type=”text/javascript”> 

Cascading Style Sheets

.style
{
	font: Arial;
	color: black;
}

 

Deakin specific info

Javascript calendars

There are two popup javscript calendars which can be used for applications. Both reside in doc_root/admin/include. See your team leader for example on how to use them.

HTML javascript editor

A WYSIWYG (what you see is what you get) textarea editor for HTML can be found at doc_root/include/tinymce2. Instructions on how to use it can be found in the accompanying docs directory.


Contributors

Simon Diderrich
Damien Brain (via contributions to below document1)
Jeremy Power

References

1DUWS II - Web PHP Application Development Framework1.3.doc
2PHP Coding standard based on Todd Hoff's C++ Coding Standard. Rewritten for PHP by Fredrik Kristiansen.