Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
563,51 KB
Nội dung
28
Chapter 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 unnecessari-
ly 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;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
29
Documentation
}
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 inter-
nal idiosyncrasies are fully documented.
Documentation can be broken down into two major categories:
n
Inline comments that explain the logic flow of the code, aimed principally at peo-
ple modifying, enhancing, or debugging the code.
n
API documentation for users who want to use the function or class without read-
ing the code itself.
The following sections describe these two types of documentation.
Inline Comments
For inline code comments, PHP supports three syntaxes:
n
C-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)
*/
n
C++-style comments—With this type of comment, everything on a line fol-
lowing // is considered a comment. Here’s an example of a C++-style comment:
// This is a c++-style comment
n
Shell/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.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
30
Chapter 1 Coding Styles
Comments should always be used to clarify code.This is a classic example of a worth-
less 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 per-
formed.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:
n
It should provide an introduction to the package or library so that end users can
quickly decide whether it is relevant to their tasks.
n
It should provide a complete listing of all public classes and functions, and it
should describe both input and output parameters.
n
It 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:
n
Documentation of protected methods
n
Examples of how to extend a class to add functionality
Finally, an API documentation system should provide the following features to a devel-
oper who is writing the code that is being documented:
n
Documentation should be inline with code.This is useful for keeping documenta-
tion up-to-date, and it ensures that the documentation is always present.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
31
Documentation
n
The 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.
n
There 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
*
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
32
Chapter 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.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
33
Documentation
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
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
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.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
35
Further Reading
Figure 1.4 demonstrates that with just a bit of effort, it’s easy to generate extremely pro-
fessional documentation.
Figure 1.4 The phpdoc rendering for Employee.
Further Reading
To find out more about phpDocumentor, including directions for availability and installa-
tion, 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.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
2
Object-Oriented Programming
Through Design Patterns
BY FAR THE LARGEST AND MOST HERALDED change in PHP5 is the complete revamp-
ing 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 chap-
ter 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”;
}
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... DB_Foo that implements neither method: < ?php require “DB/Connection.inc”; class DB_Foo implements DB_Connection {} ?> Running this class generates the following error: Fatal error: Class db_foo contains 2 abstract methods and must be declared abstract (db connection::execute, db connection:: prepare) in /Users/george /Advanced PHP/ examples/chapter-2/14 .php on line 3 PHP does not support multiple inheritance.That... $a->counter++; } print “This page has been accessed “.$a->counter.” times.\n”; ?> each access increments it by one: > php 19 .php This page has been accessed 1 times > php 19 .php This page has been accessed 2 times Overloading can also be used to provide access controls on properties As you know, PHP variables can be of any type, and you can switch between types (array, string, number, and so on) without problems.You... Executing this code: $obj = new Typed; $obj->name = array(“George”); generates the following error: > php 20 .php Type assignment error #0 typed->_ _set(name, Array ([0] => George)) called at [(null):3] #1 typed->unknown(name, Array ([0] => George)) called at [/Users/george/ Advanced PHP/ examples/chapter-2/20 .php: 28] SPL and Interators In both of the preceding examples, you created objects that you wanted... to Design Patterns expected API The most common use of adaptors in PHP is not for providing an alternative interface to one class via another (because there is a limited amount of commercial PHP code, and open code can have its interface changed directly) PHP has its roots in being a procedural language; therefore, most of the built-in PHP functions are procedural in nature When functions need to be... semantics in most other OO languages, so they have been abandoned in PHP5 In PHP5 , when you create an object, you are returned a handle to that object, which is similar in concept to a reference in C++.When you execute the preceding code under PHP5 , you only create a single instance of the object; no copies are made To actually copy an object in PHP5 , you need to use the built-in _ _clone() method In the preceding... constructor of the parent class as parent::_ _constructor(); PHP5 does not automatically call parent constructors parent is as keyword that resolves to a class’s parent class Introduction to OO Programming Encapsulation Users coming from a procedural language or PHP4 might wonder what all the public stuff floating around is.Version 5 of PHP provides data-hiding capabilities with public, protected,... explore a few patterns, mainly as a vehicle for showcasing some of the advanced OO techniques available in PHP The Adaptor Pattern The Adaptor pattern is used to provide access to an object via a specific interface In a purely OO language, the Adaptor pattern specifically addresses providing an alternative API to an object; but in PHP we most often see this pattern as providing an alternative interface... } } /* */ } In most cases, creating a destructor is not necessary because PHP cleans up resources at the end of a request For long-running scripts or scripts that open a large number of files, aggressive resource cleanup is important In PHP4 , objects are all passed by value.This meant that if you performed the following in PHP4 : $obj = new TestClass; $copy = $obj; you would actually create three copies... at a given time There are a number of methods to implement singletons in PHP5 .You could simply declare all of an object’s properties as static, but that creates a very weird syntax for dealing with the object, and you never actually use an instance of the object Here is a simple class that implements the Singleton pattern: < ?php class Singleton { static $property; public function _ _construct() {}... resources (such as file handles or database connections) that a class creates In PHP, variables are reference counted.When a variable’s reference count drops to 0, the variable is removed from the system by the garbage collector If this variable is an object, its _ _destruct() method is called The following small wrapper of the PHP file utilities showcases destructors: class IO { public $fh = false; public . to look elsewhere.
phpDocumentor is heavily inspired by JavaDoc, the automatic documentation system for
Java.
Using phpDocumentor
phpDocumentor works by. 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