Coding Standards
Page is being revised.
This document describes rules and recommendations for developing applications and class libraries using the PHP language.
Common Naming Conventions
- Always choose meaningful and specific names.
- Avoid using abbreviations unless the full name is excessive.
- Use uppercase for two-letter abbreviations, and Pascal Case for longer abbreviations.
- Use only alphanumeric characters in names
PHP Files
- For files that contain only PHP code, the closing tag (
?>) is never permitted. Not including it prevents trailing whitespace from being accidentally injected into the output. - Use an indent of 1 tab.
- The recommended line length is 80 characters, i.e. developers should aim keep code as close to the 80-column boundary as it is practical.
- PHP code must always be delimited by the full-form PHP tags:
<?php ... ?> - File name should match class name if possible.
For all other files, only alphanumeric characters, underscores, and the dash
character (-) are permitted. Spaces are prohibited. Any file that
contains any PHP code must end with the extension .php, or
.phtml in case of templates.
Strings
When a string is literal (contains no variable substitutions), the single quote must always used to demarcate the string. Exception: when a literal string itself contains apostrophes, it is permitted to demarcate the string with double quotes.
Strings may be concatenated using the . operator. A space must
always be added before and after the . operator to improve
readability. It is permitted to break the statement into multiple lines –
each successive line should be padded with whitespace such that the
. operator is aligned under the = operator:
$sql = "SELECT `id`, `name` FROM `people` "
. "WHERE `name` = 'Susan' "
. "ORDER BY `name` ASC ";
Arrays
When declaring indexed arrays, a trailing space must be added after each comma delimiter to improve readability:
$sampleArray = array(1, 2, 3, 'test');
When declaring associative arrays, it is encouraged to put each key and value pair on separated line, indented by 1 tab. After last pair the comma must be added.
$sampleArray = array(
'firstKey' => 'firstValue',
'secondKey' => 'secondValue',
);
Classes
Naming conventions:
- PascalCase
- Use a noun or noun phrase for class name.
- Add an appropriate class-suffix when sub-classing another type when possible.
- Examples: TexyParser, HttpRequest
Coding Style:
- The brace is always written on the line underneath the class name.
- Every class must have a documentation block.
- Any code within a class must be indented by 1 tab.
Placing additional code in a class file is permitted but discouraged (static constructor calling is allowed). In these files, two blank lines must separate the class from any additional PHP code in the file.
Class members implementation should follow this order as it is practical:
- Member Variables
- public
- protected
- private
- Constructor, Destructor
- Properties
- Methods
- public
- protected
- private
The ultimate ancestor of all instantiable classes should be
Nette\Object.
Interfaces
Interface classes must follow the same conventions as other classes, however
must begin with I letter. Example: IPresenter
Member variables
Naming conventions:
- camelCase
- Variables and properties must describe an entity not the type or size.
- Do not include the parent class name within a property name.
Variables should always be as verbose as practical. Terse variable names such
as $i and $n are discouraged for anything other than
the smallest loop contexts.
Variables must have documentation block with @var directive and
specified type.
Class properties
Properties are OOP enhancement provided by Nette\Object. They
must follow the same conventions as other variables. Accessors must be prefixed
with either get or set (followed by upper case letter)
and declared as public. Getter is required, setter is optional.
Example:
public function getName()
public function setName()
$obj->name
Constants
They must always have all letters capitalized, separated by underscore characters.
Example: CONTENT_TEXTUAL, FIELD_NUMERIC
Constants must be defined as class members by using the const
construct. Defining constants in the global scope with define is
permitted but discouraged.
Functions and Methods
Definitions
Naming conventions:
- camelCase
- Try to use a verb or verb-object pair.
- If method returns boolean, try to prefix name with “is”, “can”, “has” or similar meaningful prefix.
- Names must be as verbose as is practical to enhance the understandability of code.
- Examples: fetchPairs(), getElementById(), isSubmitted()
Functions in the global scope are permitted but strongly discouraged (except extension methods). It is highly recommended that these functions should be wrapped in a static class.
Methods must always declare their visibility by using one of the
private, protected, or public
constructs.
Like classes, the brace is always written on the line underneath the function name. There is no space between the function name and the opening parenthesis for the arguments. All arguments should have type hint if possible.
Functions and methods must have documentation block with @param
directive and specified types of all of the arguments.
This is an example of an acceptable function declaration in a class:
/**
* Documentation block here
*/
class Foo
{
/**
* Documentation block here
*/
public function verb()
{
// entire content of function
// must be indented by 1 tab
}
}
The return value must not be enclosed in parentheses. This can hinder readability and can also break code if a method is later changed to return by reference.
Usage
Function arguments are separated by a single trailing space after the comma delimiter. This is an example of an acceptable function call for a function that takes three arguments:
fooBar(1, 2, 3);
Call-time pass by-reference is prohibited.
For functions whose arguments permitted arrays, the function call may include the “array” construct and can be split into multiple lines to improve readability. In these cases, the standards for writing arrays still apply:
fooBar(array(1, 2, 3), 2, 3);
fooBar(1, 2, array(
'firstKey' => 'firstValue',
'secondKey' => 'secondValue',
), 3, 4);
Control Statements
if else based
statements
Control statements based on the if and elseif
constructs must have a single space before the opening parenthesis of the
conditional, and a single space after the closing parenthesis.
The opening brace is written on the same line as the conditional statement.
The closing brace is always written on its own line. If there is an
elseif or else section after the if or
elseif, there is one empty line before closing brace of this
preceding section. Any content within the braces must be indented by 1 tab.
Comparison “strong typed” operators (=== and
!==) are preferred before “weak typed” ones (==
and !=). If weak typed comparison operator is used, the intention
must be documented with a comment.
if ($a != 2) { // intentionally !=
$a = 2;
}
For if statements that include elseif or
else, the formatting must be as in these examples:
if ($a !== 2) {
$a = 2;
} elseif ($a === 3) {
$a = 4;
} else {
$a = 7;
}
switch based statements
Control statements written with the switch construct must have a
single space before the opening parenthesis of the conditional statement, and
also a single space after the closing parenthesis.
All content under each case (or default) statement
must be indented by 1 tab.
switch ($numPeople) {
case 1:
break;
case 2:
break;
default:
break;
}
It is sometimes useful to write a case statement which falls through to the
next case by not including a break or return in that case. To distinguish these
cases from bugs, any case statement where break or return are omitted must
contain the comment // break intentionally omitted.