
Advanced PHP Programming
.pdf
28Chapter 1 Coding Styles
Compare this with the following:
<table>
<tr><td>Name</td><td>Position</td></tr>
<?php foreach ($employees as $employee) { ?>
<tr><td><? echo $employee[‘name’] ?></td><td><? echo $employee[‘position’] ?></td></tr>
<?php } ?>
</table>
The second code fragment is cleaner and does not obfuscate the HTML by unnecessarily using echo. As a note, using the <?= ?> syntax, which is identical to <?php echo ?>, requires the use of short_tags, which there are good reasons to avoid.
print Versus echo
print and echo are aliases for each other; that is, internal to the engine, they are indistinguishable. You should pick one and use it consistently to make your code easier to read.
Using Parentheses Judiciously
You should use parentheses to add clarity to code.You can write this:
if($month == ‘february’) {
if($year % 4 == 0 && $year % 100 || $year % 400 == 0) { $days_in_month = 29;
}
else {
$days_in_month = 28;
}
}
However, this forces the reader to remember the order of operator precedence in order to follow how the expression is computed. In the following example, parentheses are used to visually reinforce operator precedence so that the logic is easy to follow:
if($month == ‘february’) {
if((($year % 4 == 0 )&& ($year % 100)) || ($year % 400 == 0)) { $days_in_month = 29;
}
else {
$days_in_month = 28;
}
}
You should not go overboard with parentheses, however. Consider this example: if($month == ‘february’) {
if(((($year % 4) == 0 )&& (($year % 100) != 0)) || (($year % 400) == 0 )) { $days_in_month = 29;

Documentation 29
}
else {
$days_in_month = 28;
}
}
This expression is overburdened with parentheses, and it is just as difficult to decipher the intention of the code as is the example that relies on operator precedence alone.
Documentation
Documentation is inherently important in writing quality code. Although well-written code is largely self-documenting, a programmer must still read the code in order to understand its function. In my company, code produced for clients is not considered complete until its entire external application programming interface (API) and any internal idiosyncrasies are fully documented.
Documentation can be broken down into two major categories:
nInline comments that explain the logic flow of the code, aimed principally at people modifying, enhancing, or debugging the code.
nAPI documentation for users who want to use the function or class without reading the code itself.
The following sections describe these two types of documentation.
Inline Comments
For inline code comments, PHP supports three syntaxes:
nC-style comments—With this type of comment, everything between /* and */ is considered a comment. Here’s an example of a C-style comment:
/* This is a c-style comment
* (continued)
*/
nC++-style comments—With this type of comment, everything on a line following // is considered a comment. Here’s an example of a C++-style comment:
// This is a c++-style comment
nShell/Perl-style comments—With this type of comment, the pound sign (#) is the comment delimiter. Here’s an example of a Shell/Perl-style comment:
# This is a shell-style comment
In practice, I avoid using Shell/Perl-style comments entirely. I use C-style comments for large comment blocks and C++-style comments for single-line comments.

30 Chapter 1 Coding Styles
Comments should always be used to clarify code.This is a classic example of a worthless comment:
// increment i
i++;
This comment simply reiterates what the operator does (which should be obvious to anyone reading the code) without lending any useful insight into why it is being performed.Vacuous comments only clutter the code.
In the following example, the comment adds value:
//Use the bitwise “AND” operatorest to see if the first bit in $i is set
//to determine if $i is odd/even
if($i & 1) {
return true;
}
It explains that we are checking to see whether the first bit is set because if it is, the number is odd.
API Documentation
Documenting an API for external users is different from documenting code inline. In API documentation, the goal is to ensure that developers don’t have to look at the code at all to understand how it is to be used. API documentation is essential for PHP libraries that are shipped as part of a product and is extremely useful for documenting libraries that are internal to an engineering team as well.
These are the basic goals of API documentation:
nIt should provide an introduction to the package or library so that end users can quickly decide whether it is relevant to their tasks.
nIt should provide a complete listing of all public classes and functions, and it should describe both input and output parameters.
nIt should provide a tutorial or usage examples to demonstrate explicitly how the code should be used.
In addition, it is often useful to provide the following to end users:
nDocumentation of protected methods
nExamples of how to extend a class to add functionality
Finally, an API documentation system should provide the following features to a developer who is writing the code that is being documented:
nDocumentation should be inline with code.This is useful for keeping documentation up-to-date, and it ensures that the documentation is always present.

Documentation 31
nThe documentation system should have an easy and convenient syntax.Writing documentation is seldom fun, so making it as easy as possible helps ensure that it gets done.
nThere should be a system for generating beautified documentation.This means that the documentation should be easily rendered in a professional and easy-to- read format.
You could opt to build your own system for managing API documentation, or you could use an existing package. A central theme throughout this book is learning to make good decisions regarding when it’s a good idea to reinvent the wheel. In the case of inline documentation, the phpDocumentor project has done an excellent job of creating a tool that satisfies all our requirements, so there is little reason to look elsewhere. phpDocumentor is heavily inspired by JavaDoc, the automatic documentation system for Java.
Using phpDocumentor
phpDocumentor works by parsing special comments in code.The comment blocks all take this form:
/**
*Short Description
*Long Description
*@tags
*/
Short Description is a short (one-line) summary of the item described by the block. Long Description is an arbitrarily verbose text block. Long Description allows for HTML in the comments for specific formatting. tags is a list of phpDocumentor tags. The following are some important phpDocumentor tags:
Tag Description |
|
@package [package name] |
The package name |
@author [author name] |
The author information |
@var [type] |
The type for the var statement following the |
|
comment |
@param [type [description]]
The type for the input parameters for the function following the block
@return [type [description]] The type for the output of the function
You start the documentation by creating a header block for the file:
/**
* This is an example page summary block
*

32Chapter 1 Coding Styles
*This is a longer description where we can
*list information in more detail.
*@package Primes
*@author George Schlossnagle
*/
This block should explain what the file is being used for, and it should set @package for the file. Unless @package is overridden in an individual class or function, it will be inherited by any other phpDocumentor blocks in the file.
Next, you write some documentation for a function. phpDocumentor tries its best to be smart, but it needs some help. A function’s or class’s documentation comment must immediately precede its declaration; otherwise, it will be applied to the intervening code instead. Note that the following example specifies @param for the one input parameter for the function, as well as @return to detail what the function returns:
/**
*Determines whether a number is prime (stupidly)
*Determines whether a number is prime or not in
*about the slowest way possible.
*<code>
*for($i=0; $i<100; $i++) {
*if(is_prime($i)) {
*echo “$i is prime\n”;
*}
*}
*</code>
*@param integer
*@return boolean true if prime, false elsewise
*/
function is_prime($num)
{
for($i=2; $i<= (int)sqrt($num); $i++) { if($num % $i == 0) {
return false;
}
}
return true;
}
?>
This seems like a lot of work. Let’s see what it has bought us.You can run phpDocumentor at this point, as follows:
phpdoc -f Primes.php -o HTML:frames:phpedit -t /Users/george/docs
Figure 1.3 shows the result of running this command.

Documentation 33
Figure 1.3 phpdoc output for primes.php.
For a slightly more complicated example, look at this basic Employee class:
<?php
/**
*A simple class describing employees
*@package Employee
*@author George Schlossnagle
*/
/**
* An example of documenting a class */
class Employee
{
/**
* @var string */
var $name; /**
*The employees annual salary
*@var number

34 Chapter 1 Coding Styles
*/
var $salary; /**
* @var number */
var $employee_id;
/**
*The class constructor
*@param number
*/
function Employee($employee_id = false)
{
if($employee_id) { $this->employee_id = $employee_id; $this->_fetchInfo();
}
}
/**
*Fetches info for employee
*@access private
*/
function _fetchInfo()
{
$query = “SELECT name, salary FROM employees
WHERE employee_id = $this->employee_id”; $result = mysql_query($query);
list($this->name, $this->department_id) = mysql_fetch_row($result);
}
/**
*Returns the monthly salary for the employee
*@returns number Monthly salary in dollars
*/
function monthlySalary()
{
return $this->salary/12;
}
}
?>
Note that _fetchInfo is @access private, which means that it will not be rendered by
phpdoc.

Further Reading |
35 |
Figure 1.4 demonstrates that with just a bit of effort, it’s easy to generate extremely professional documentation.
Figure 1.4 The phpdoc rendering for Employee.
Further Reading
To find out more about phpDocumentor, including directions for availability and installation, go to the project page at www.phpdoc.org.
The Java style guide is an interesting read for anyone contemplating creating coding standards.The official style guide is available from Sun at http://java.sun.com/ docs/codeconv/html/CodeConvTOC.doc.html.


2
Object-Oriented Programming
Through Design Patterns
BY FAR THE LARGEST AND MOST HERALDED change in PHP5 is the complete revamping of the object model and the greatly improved support for standard object-oriented (OO) methodologies and techniques.This book is not focused on OO programming techniques, nor is it about design patterns.There are a number of excellent texts on both subjects (a list of suggested reading appears at the end of this chapter). Instead, this chapter is an overview of the OO features in PHP5 and of some common design patterns.
I have a rather agnostic view toward OO programming in PHP. For many problems, using OO methods is like using a hammer to kill a fly.The level of abstraction that they offer is unnecessary to handle simple tasks.The more complex the system, though, the more OO methods become a viable candidate for a solution. I have worked on some large architectures that really benefited from the modular design encouraged by OO techniques.
This chapter provides an overview of the advanced OO features now available in PHP. Some of the examples developed here will be used throughout the rest of this book and will hopefully serve as a demonstration that certain problems really benefit from the OO approach.
OO programming represents a paradigm shift from procedural programming, which is the traditional technique for PHP programmers. In procedural programming, you have data (stored in variables) that you pass to functions, which perform operations on the data and may modify it or create new data. A procedural program is traditionally a list of instructions that are followed in order, using control flow statements, functions, and so on.The following is an example of procedural code:
<?php
function hello($name)
{
return “Hello $name!\n”;
}