Code conventions contain rules and recommendations about visual formating of the code. They are important for the humans, not for the computers.
Code conventions are important to programmers for a number of reasons:
80% of the lifetime cost of a piece of software goes to maintenance.
Hardly any software is maintained for its whole life by the original author.
Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.
If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.
For the conventions to work, every person writing software must conform to the code conventions. Everyone.
.class.php – file containing class definition
.inc.php – file containing functions or straight code
.conf – file containing configuration key-value pairs
.php – runnable scripts
.tpl – html template files
README - The preferred name for the file that summarizes the contents of a particular directory.
TODO - The preferred name for the file that contain TODO items
Files longer than 500 lines should be avoided.
A file consists of sections that should be separated by blank lines and an optional comment identifying each section. Section separation is recommended to be done with 2 blank lines.
All files should begin with single line comment containing product name – this helps to detect problems in code that is mistakenly grabbed from another project.
Optionally may have $Id expandable CVS/SVN tag.
Other lines may be specified by conventions of given product.
Always use require_once() statement. Using require() is deprecated.
Include() statements also have to be avoided (they don't make sense in pure php context).
Put first require_once() statements that include general libraries and after them require_once() that include application/site specific files (this is common sense – application specific files is natural to depend on libraries).
It is strongly recommended to keep all of your require_once() statement at top of the file, just after the beginning comments. Failing to comply with that may lead to confusion and unrepeatable bugs that are hard to find. Usage of “inner” require_once is acceptable only in “low” level code as libraries or startup (boot) scripts that are normally not visible to end user (developer).
Conditional require_once should be avoided at all – that is a sign of bad design.
“Autoloading” (automatic loading via __autoload function or another method) may sound as good idea, but it also makes code harder to read and comprehend.
Both conditional includes and autoloading are generally bad idea because of lack of namespaces in PHP – it is easy global variables to be overwrited in some autoloaded code.
Code section can contain class/interface definition OR either global function definitions OR global code.
Comment describing class purpose, used algorithms, assumptions, etc.
First public, then protected, then private.
It is good idea to put first public methods, with the following exception: methods should be grouped by functionality rather than by scope or accessibility. For example, a private class method can be in between two public instance methods. The goal is to make reading and understanding the code easier.
Methods have to be separated by two blank lines.
Each function can be preceded by optional comment.
Functions have to be separated by two blank lines.
Each code that is contained in a file outside of methods and functions should be considered global (because of the rules for require() statements.
Global code is allowed only in startup/boot scripts.
Tab with size 4 spaces must be used for indentation.
Avoid lines longer than 100 characters, since they're not handled well by many terminals and tools.
Note: Examples for use in documentation should have a shorter line length-generally no more than 90 characters.
When an expression will not fit on a single line, break it according to these general principles:
Align the new line with the beginning of the expression at the same level on the previous line.
If the above rules lead to confusing code or to code that's squished up against the right margin, just indent 8 spaces instead.
Here are some examples of breaking method calls:
some_method($long_expression1, $long_expression2, $long_expression3,
$long_expression4, $long_expression5);
$var = some_method($long_expression1,
some_method2($long_expression2,
$long_expression3)); Following are two examples of breaking an arithmetic expression. The first is preferred, since the break occurs outside the parenthesized expression, which is at a higher level.
$long_name1 = $long_name2 * ($long_name3 + $long_name4 - $long_name5)
+ 4 * $long_name6; // PREFER
$long_name1 = $long_name2 * ($long_name3 + $long_name4
- $long_name5) + 4 * $long_name6; // AVOID
Following are two examples of indenting method declarations. The first is the conventional case. The second would shift the second and third lines to the far right if it used conventional indentation, so instead it indents only 2 tabs.
//CONVENTIONAL INDENTATION
public function some_method($an_arg, Object $another_arg, $yet_another_arg, Object $and_still_another) {
...
}
//INDENT 2 TABS TO AVOID VERY DEEP INDENTS
private static horking_long_method_nName($an_arg,
Object another_arg, $yet_another_arg,
Object and_still_another) {
...
}
Line wrapping for if
statements should generally use the 2-tabs rule, since conventional
(1 tab) indentation makes seeing the body difficult. For example:
//DON'T USE THIS INDENTATION
if (($condition1 && $condition2)
|| ($condition3 && $condition4)
||!($condition5 && $condition6)) { //BAD WRAPS
do_something_about_it(); //MAKE THIS LINE EASY TO MISS
}
//USE THIS INDENTATION INSTEAD
if (($condition1 && $condition2)
|| ($condition3 && $condition4)
||!($condition5 && $condition6)) {
do_something_about_it();
}
//OR USE THIS
if (($condition1 && $condition2) || ($condition3 && $condition4)
||!($condition5 && $condition6)) {
do_somethings_about_it();
}
Here are three acceptable ways to format ternary expressions:
$alpha = (aLongBooleanExpression) ? $beta : $gamma;
$alpha = (aLongBooleanExpression) ? $beta
: $gamma;
$alpha = (aLongBooleanExpression)
? $beta
: $gamma; PHP code can have two kinds of comments: implementation comments and documentation comments. Implementation comments are those found in C++, which are delimited by /*...*/, and //. Documentation comments (known as "doc comments") are delimited by /**...*/. Doc comments can be extracted to HTML files using the phpdoc tool.
Implementation comments are mean for commenting out code or for comments about the particular implementation. Doc comments are meant to describe the specification of the code, from an implementation-free perspective. to be read by developers who might not necessarily have the source code at hand.
Comments should be used to give overviews of code and provide additional information that is not readily available in the code itself. Comments should contain only information that is relevant to reading and understanding the program. For example, information about how the corresponding package is built or in what directory it resides should not be included as a comment.
Discussion of nontrivial or non obvious design decisions is appropriate, but avoid duplicating information that is present in (and clear from) the code. It is too easy for redundant comments to get out of date. In general, avoid any comments that are likely to get out of date as the code evolves.
Note:The frequency of comments sometimes reflects poor quality of code. When you feel compelled to add a comment, consider rewriting the code to make it clearer.
Comments should not be enclosed in large boxes
drawn with asterisks or other characters.
Comments should never
include special characters such as form-feed and backspace.
Programs can have four styles of implementation comments: block, single-line, trailing, and end-of-line.
Block comments are used to provide descriptions of files, methods, data structures and algorithms. Block comments may be used at the beginning of each file and before each method. They can also be used in other places, such as within methods. Block comments inside a function or method should be indented to the same level as the code they describe.
A block comment should be preceded by a blank line to set it apart from the rest of the code.
/* * Here is a block comment. */
Short comments can appear on a single line indented to the level of the code that follows. If a comment can't be written in a single line, it should follow the block comment format. A single-line comment should be preceded by a blank line. Here's an example of a single-line comment in PHP code:
if ($condition) {
/* Handle the condition. */
...
}Very short comments can appear on the same line as the code they describe, but should be shifted far enough to separate them from the statements. If more than one short comment appears in a chunk of code, they should all be indented to the same tab setting.
Here's an example of a trailing comment in Java code:
if ($a == 2) {
return TRUE; /* special case */
} else {
return is_prime($a); /* works only for odd a */
}The // comment delimiter can
comment out a complete line or only a partial line. It shouldn't be
used on consecutive multiple lines for text comments; however, it can
be used in consecutive multiple lines for commenting out sections of
code. Examples of all three styles follow:
if ($foo > 1) {
// Do a double-flip.
...
}
else {
return false; // Explain why here.
}
//if ($bar > 1) {
//
// // Do a triple-flip.
// ...
//}
//else {
// return false;
//}PHP itself doesn't require explicit declaration of normal (non class members) variables.
One declaration per line is recommended since it encourages commenting. In other words,
private $level; // indentation level private $size; // size of table
private $level, $size;
Note: The examples above use one space between the type and the identifier. Another acceptable alternative is to use tabs, e.g.:
private $level; // indentation level private $size; // size of table protected $current_entry; // currently selected table entry
Always initialize new variables with meaningful values.
$c = 0;
while ($c < $a) {
// do something...
$c++;
}
$length = strlen($a);
When coding PHP classes and interfaces, the following formatting rules should be followed:
No space between a method name and the parenthesis "(" starting its parameter list
Open brace "{" appears at the end of the same line as the declaration statement
Closing brace "}" starts a line by itself indented to match its corresponding opening statement, except when it is a null statement the "}" should appear immediately after the "{"
class Sample extends Object {
public $ivar1;
public $ivar2;
public function Sample($i, $j) {
$this->ivar1 = $i;
$this->ivar2 = $j;
}
public function empty_method() {}
...
}
Each line should contain at most one statement. Example:
$argv++; // Correct $argc--; // Correct $argv++; $argc--; // AVOID!
Compound statements are statements that
contain lists of statements enclosed in braces "{
statements }". See the following sections for examples.
The enclosed statements should be indented one more level than the compound statement.
The opening brace should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement.
Braces are used around all statements, even single
statements, when they are part of a control structure, such as a
if-else or for statement. This makes it
easier to add statements without accidentally introducing bugs due
to forgetting to add braces.
A return statement with a value
should not use parentheses unless they make the return value more
obvious in some way. Example:
return; return $my_disk->size(); return ($size ? $size : $default_size);
The if-else class of statements
should have the following form:
if (condition) {
statements;
}
if (condition) {
statements;
} else {
statements;
}
if (condition) {
statements;
} else if (condition) {
statements;
} else{
statements;
}
Note: if statements always use braces {}. Avoid
the following error-prone form:
if (condition) //AVOID! THIS OMITS THE BRACES {}!
statement;A for statement should have the
following form:
for (initialization; condition; update) {
statements;
}
An empty for statement (one in which
all the work is done in the initialization, condition, and update
clauses) should have the following form:
for (initialization; condition; update);
When using the comma operator in the initialization
or update clause of a for statement, avoid the
complexity of using more than three variables. If needed, use
separate statements before the for loop (for the
initialization clause) or at the end of the loop (for the update
clause).
A while statement should have the
following form:
while (condition) {
statements;
}
An empty while statement should have
the following form:
while (condition);
A do-while statement should have
the following form:
do {
statements;
} while (condition);A switch statement should have the
following form:
switch (condition) {
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
Every time a case falls through (doesn't include
a break statement), add a comment where the break
statement would normally be. This is shown in the preceding code
example with the /* falls through */ comment.
Every switch statement should
include a default case. The break in the default case is
redundant, but it prevents a fall-through error if later another case
is added.
A try-catch statement should have
the following format:
try {
statements;
} catch (Exception_Class $e) {
statements;
}Blank lines improve readability by setting off sections of code that are logically related.
Two blank lines should always be used in the following circumstances:
One blank line should always be used in the following circumstances:
Between the local variables in a method and its first statement
Between logical sections inside a method to improve readability
Blank spaces should be used in the following circumstances:
while (true) {
...
}
Note that a blank space should not be used between a method name and its opening parenthesis. This helps to distinguish keywords from method calls.
All binary operators should be separated from their operands by spaces. Blank spaces should never separate unary operators such as unary minus, increment ("++"), and decrement ("--") from their operands. Example:
$a += $c + $d;
$a = ($a + $b) / ($c * $d);
while ($d++ = $s++) {
$n++;
}
print_size("size is " + $foo + "\n");
for (expr1; expr2; expr3)
my_method((string) $aNum, (string) $x);
my_method((int) ($cp + 5), ((int) ($i + 3))
+ 1);Class names should be nouns, first letter of each internal word capitalized, words separated by underscore (_). Try to keep your class names simple and descriptive. Use whole words-avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as URL or HTML).
Examples: class Form, class Guarded_Form.
Methods should be verbs, in lower case, words separated by underscore;
Example: public function calculate_total($customer_id);
Variables should be in lower case, words separated by underscore.
Example: $customer_total = $acc->calculate_total($customer_id);
Constants (defined with define()) should be in upper case, words separated by underscore.
Example: define('MY_CONSTANT', 5);
Class constants (defined with const) should be in upper case, words separated by underscore.
Example:
class Some_Class {
const $my_const = 5;
Don't make any instance or class variable public without good reason. In general avoid usage of public class members.
Avoid using an object to access a class (static) variable or method. Use a class name instead. For example:
Some_Class::class_static_method(); //OK an_object->class_static_method(); //AVOID!
Numerical constants (literals) should not be
coded directly, except for -1, 0, and 1, which can appear in a for
loop as counter values.
It is generally a good idea to use parentheses liberally in expressions involving mixed operators to avoid operator precedence problems. Even if the operator precedence seems clear to you, it might not be to others-you shouldn't assume that other programmers know precedence as well as you do.
if ($a == $b && $c == $d) // AVOID! if (($a == $b) && ($c == $d)) // RIGHT
Try to make the structure of your program match the intent. Example:
if (booleanExpression) {
return true;
} else {
return false;
}
return booleanExpression;
if (condition) {
return $x;
}
return $y;
return (condition ? $x : $y);
If an expression containing a binary operator
appears before the ? in the ternary ?: operator,
it should be parenthesized. Example:
($x >= 0) ? $x : -$x;
TODO comments should have following syntax:
// TODO – description what have to be done so code to be completed
or
/* TODO – long description what have to be done so code to be completed that spans on multiple rows */
TODO comments should be used to mark places that are not yet finished to full extend.
Example:
for($i=1; $i <= $max_c; $i++) {
//TODO – put check to skip calculating balance when client
// doesn't have any transactions
$client->calculate_balance();
}Use XXX in a comment to flag something that is bogus
but works.
Use FIXME in a comment to flag something that is
bogus and broken.
This document used as a base “Code
Conventions for the JavaTM programming
Language” (http://java.sun.com/docs/codeconv).
Although it is heavy modified any copying, adapting, and redistribing
of this document have to comply with original copyright notice of Sun
(http://java.sun.com/docs/codeconv/html/Copyright.doc.html).
Adapted with permission from CODE
CONVENTIONS FOR THE JAVATM PROGRAMMING
LANGUAGE. Copyright 1995-1999 Sun Microsytems, Inc. All rights
reserved.
Java is trademark of Sun Microsystem.
All trademarks used in this documents are property of their respective owners and are used for identification purposes only.