Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Advanced PHP Programming

.pdf
Скачиваний:
67
Добавлен:
14.04.2015
Размер:
7.82 Mб
Скачать

1

Coding Styles

“Everything should be made as simple as possible, but not one bit simpler.”

—Albert Einstein (1879–1955)

“Seek simplicity, and distrust it.”

—Alfred North Whitehead (1861–1947)

NO MATTER WHAT YOUR PROFICIENCY LEVEL in PHP, no matter how familiar you are

with the language internals or the idiosyncrasies of various functions or syntaxes, it is easy to write sloppy or obfuscated code. Hard-to-read code is difficult to maintain and debug. Poor coding style connotes a lack of professionalism.

If you were to stay at a job the rest of your life and no one else had to maintain your code, it would still not be acceptable to write poorly structured code.Troubleshooting and augmenting libraries that I wrote two or three years ago is difficult, even when the style is clean.When I stray into code that I authored in poor style, it often takes as long to figure out the logic as it would to have just re-implemented the library from scratch.

To complicate matters, none of us code in a vacuum. Our code needs to be maintained by our current and future peers.The union of two styles that are independently readable can be as unreadable and unmaintainable as if there were no style guide at all. Therefore, it is important not only that we use a style that is readable, but that we use a style that is consistent across all the developers working together.

10 Chapter 1 Coding Styles

I once inherited a code base of some 200,000 lines, developed by three teams of developers.When we were lucky, a single include would at least be internally consis- tent—but often a file would manifest three different styles scattered throughout.

Choosing a Style That Is Right for You

Choosing a coding style should not be something that you enter into lightly. Our code lives on past us, and making a style change down the line is often more trouble than it’s worth. Code that accumulates different styles with every new lead developer can quickly become a jumbled mess.

As important as it is to be able to choose a new style in a project absent of one, you also need to learn to adhere to other standards.There is no such thing as a perfect standard; coding style is largely a matter of personal preference. Much more valuable than choosing “the perfect style” is having a consistent style across all your code.You shouldn’t be too hasty to change a consistent style you don’t particularly like.

Code Formatting and Layout

Code formatting and layout—which includes indentation, line length, use of whitespace, and use of Structured Query Language (SQL)—is the most basic tool you can use to reinforce the logical structure of your code.

Indentation

This book uses indentation to organize code and signify code blocks.The importance of indentation for code organization cannot be exaggerated. Many programmers consider it such a necessity that the Python scripting language actually uses indentation as syntax; if Python code is not correctly indented, the program will not parse!

Although indentation is not mandatory in PHP, it is a powerful visual organization tool that you should always consistently apply to code.

Consider the following code:

if($month == september|| $month == april|| $month == june|| $month == november) { return 30;

}

else if($month == february) {

if((($year % 4 == 0) && !($year % 100)) || ($year % 400 == 0)) { return 29;

}

else { return 28;

}

}

else { return 31;

}

Code Formatting and Layout

11

Compare that with the following block that is identical except for indentation:

if($month

== september||

$month

== april

||

$month

== june

||

$month

== november) {

return 30;

 

}

 

 

else if($month == february) {

if((($year % 4 == 0) && ($year % 100)) || ($year % 400 == 0)) { return 29;

}

else { return 28;

}

}

else { return 31;

}

In the latter version of this code, it is easier to distinguish the flow of logic than in the first version.

When you’re using tabs to indent code, you need to make a consistent decision about whether the tabs are hard or soft. Hard tabs are regular tabs. Soft tabs are not really tabs at all; each soft tab is actually represented by a certain number of regular spaces.The benefit of using soft tabs is that they always appear the same, regardless of the editor’s tab-spacing setting. I prefer to use soft tabs.With soft tabs set and enforced, it is easy to maintain consistent indentation and whitespace treatment throughout code.When you use hard tabs, especially if there are multiple developers using different editors, it is very easy for mixed levels of indentation to be introduced.

Consider Figure 1.1 and Figure 1.2; they both implement exactly the same code, but one is obtuse and the other easy to read.

Figure 1.1 Properly indented code.

12 Chapter 1 Coding Styles

Figure 1.2 The same code as in Figure 1.1, reformatted in a different browser.

You must also choose the tab width that you want to use. I have found that a tab width of four spaces produces code that is readable and still allows a reasonable amount of nesting. Because book pages are somewhat smaller than terminal windows, I use two space tab-widths in all code examples in this book.

Many editors support auto-detection of formatting based on “magic” comments in the source code. For example, in vim, the following comment automatically sets an editor to use soft tabs (the expandtab option) and set their width to four spaces (the tabstop and softtabstop options):

// vim: expandtab softtabstop=2 tabstop=2 shiftwidth=2

In addition, the vim command :retab will convert all your hard tabs to soft tabs in your document, so you should use it if you need to switch a document from using tabs to using spaces.

In emacs, the following comment achieves the same effect:

/*

*Local variables:

*tab-width: 2

*c-basic-offset: 2

*indent-tabs-mode: nil

*End:

*/

In many large projects (including the PHP language itself), these types of comments are placed at the bottom of every file to help ensure that developers adhere to the indentation rules for the project.

Code Formatting and Layout

13

Line Length

The first line of the how-many-days-in-a-month function was rather long, and it is easy to lose track of the precedence of the tested values. In cases like this, you should split the long line into multiple lines, like this:

if($month == september|| $month == april|| $month == june|| $month == november) {

return 30;

}

You can indent the second line to signify the association with the upper. For particularly long lines, you can indent and align every condition:

if($month

== september||

$month

== april||

$month

== june||

$month

== november)

{

 

return 30;

}

This methodology works equally well for functions’ parameters:

mail(postmaster@example.foo,

My Subject,

$message_body,

From: George Schlossnagle <george@omniti.com>\r\n);

In general, I try to break up any line that is longer than 80 characters because 80 characters is the width of a standard Unix terminal window and is a reasonable width for printing to hard copy in a readable font.

Using Whitespace

You can use whitespace to provide and reinforce logical structure in code. For example, you can effectively use whitespace to group assignments and show associations.The following example is poorly formatted and difficult to read:

$lt = localtime(); $name = $_GET[name]; $email = $_GET[email];

$month = $lt[tm_mon] + 1; $year = $lt[tm_year] + 1900; $day = $lt[tm_day]; $address = $_GET[address];

You can improve this code block by using whitespace to logically group related assignments together and align them on =:

14 Chapter 1 Coding Styles

$name

 

= $_GET[name];

$email

 

= $_GET[email];

$address

= $_GET[address];

$lt

=

localtime();

$day

=

$lt[tm_day];

$month =

$lt[tm_mon] + 1;

$year

=

$lt[tm_year] + 1900;

SQL Guidelines

All the code formatting and layout rules developed so far in this chapter apply equally to PHP and SQL code. Databases are a persistent component of most modern Web architectures, so SQL is ubiquitous in most code bases. SQL queries, especially in database systems that support complex subqueries, can become convoluted and obfuscated. As with PHP code, you shouldn’t be afraid of using whitespace and line breaks in SQL code.

Consider the following query:

$query = SELECT FirstName, LastName FROM employees, departments WHERE employees.dept_id = department.dept_id AND department.Name = Engineering’”;

This is a simple query, but it is poorly organized.You can improve its organization in a number of ways, including the following:

nCapitalize keywords

nBreak lines on keywords

nUse table aliases to keep the code clean

Here’s an example of implementing these changes in the query:

$query = SELECT firstname,

lastname

FROM employees e,

departments d

WHERE u.dept_id = d.dept_id

AND d.name = Engineering’”;

Control Flow Constructs

Control flow constructs are a fundamental element that modern programming languages almost always contain. Control flow constructs regulate the order in which statements in a program are executed.Two types of control flow constructs are conditionals and loops. Statements that are performed only if a certain condition is true are conditionals, and statements that are executed repeatedly are loops.

$name

Code Formatting and Layout

15

The ability to test and act on conditionals allows you to implement logic to make decisions in code. Similarly, loops allow you to execute the same logic repeatedly, performing complex tasks on unspecified data.

Using Braces in Control Structures

PHP adopts much of its syntax from the C programming language. As in C, a single-line conditional statement in PHP does not require braces. For example, the following code executes correctly:

if(isset($name)) echo Hello $name;

However, although this is completely valid syntax, you should not use it.When you omit braces, it is difficult to modify the code without making mistakes. For example, if you wanted to add an extra line to this example, where is set, and weren’t paying close attention, you might write it like this:

if(isset($name)) echo Hello $name;

$known_user = true;

This code would not at all do what you intended. $known_user is unconditionally set to true, even though we only wanted to set it if $name was also set.Therefore, to avoid confusion, you should always use braces, even when only a single statement is being conditionally executed:

if(isset($name)) { echo Hello $name;

}

else {

echo Hello Stranger;

}

Consistently Using Braces

You need to choose a consistent method for placing braces on the ends of conditionals. There are three common methods for placing braces relative to conditionals:

nBSD style, in which the braces are placed on the line following the conditional, with the braces outdented to align with the keyword:

if ($condition)

{

// statement

}

nGNU style, in which the braces appear on the line following the conditional but are indented halfway between the outer and inner indents:

16 Chapter 1 Coding Styles

if ($condition)

{

// statement

}

nK&R style, in which the opening brace is placed on the same line as the keyword:

if ($condition) {

// statement

}

The K&R style is named for Kernighan and Ritchie, who wrote their uber-classic

The C Programming Language by using this style.

Discussing brace styles is almost like discussing religion. As an idea of how contentious this issue can be, the K&R style is sometimes referred to as “the one true brace style.” Which brace style you choose is ultimately unimportant; just making a choice and sticking with it is important. Given my druthers, I like the conciseness of the K&R style, except when conditionals are broken across multiple lines, at which time I find the BSD style to add clarity. I also personally prefer to use a BSD-style bracing convention for function and class declarations, as in the following example:

Function hello($name)

{

echo Hello $name\n;

}

The fact that function declarations are usually completely outdented (that is, up against the left margin) makes it easy to distinguish function declarations at a glance.When coming into a project with an established style guide, I conform my code to that, even if it’s different from the style I personally prefer. Unless a style is particularly bad, consistency is more important than any particular element of the style.

for Versus while Versus foreach

You should not use a while loop where a for or foreach loop will do. Consider this code:

function is_prime($number)

{

$i = 2;

while($i < $number) {

if ( ($number % $i ) == 0) { return false;

}

$i++;

Code Formatting and Layout

17

}

return true;

}

This loop is not terribly robust. Consider what happens if you casually add a control flow branchpoint, as in this example:

function is_prime($number)

{

If(($number % 2) != 0) {

return true;

}

$i = 0;

while($i < $number) {

// A cheap check to see if $i is even if( ($i & 1) == 0 ) {

continue;

}

if ( ($number % $i ) == 0) { return false;

}

$i++;

}

return true;

}

In this example, you first check the number to see whether it is divisible by 2. If it is not divisible by 2, you no longer need to check whether it is divisible by any even number (because all even numbers share a common factor of 2).You have accidentally preempted the increment operation here and will loop indefinitely.

Using for is more natural for iteration, as in this example:

function is_prime($number)

{

if(($number % 2) != 0) { return true;

}

for($i=0; $i < $number; $i++) {

// A cheap check to see if $i is even if( ($i & 1) == 0 ) {

continue;

}

if ( ($number % $i ) == 0) { return false;

}

}

return true;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]