Obsah
Coding standard
Stránka není aktualizovaná
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.
- When using camelCase or PascalCase, underscores are permitted.
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 is practical.
- PHP code must always be delimited by the full-form PHP tags:
<?php ... ?> - Always match class name and file name.
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 put each key and value pair on separated line, padded with 4 spaces. After last pair must be added comma.
$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.
- Prefix class names with namespace.
- Examples: TexyParser, NHttpRequest
Coding Style:
- The brace is always written on the line underneath the class name.
- Every class must have a documentation block that conforms to the PHPDocumentor standard.
- Any code within a class must be indented four spaces.
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 must follow this order:
- Member Variables
- public
- protected
- private
- Constructor, Destructor
- Properties
- Methods
- public
- protected
- private
The ultimate ancestor of all instantiable classes should be NObject. The ultimate ancestor of all uninstantiable classes should be NClass.
Interfaces
Interface classes must follow the same conventions as other classes, however
must end with the word Interface. Example: DibiDriverInterface
Variables
Naming conventions:
- camelCase
- Variables and properties should describe an entity not the type or size.
- Do not include the parent class name within a property name.
For class member variables that are declared as private, the
first character of the variable name may be a single underscore to improve
readability. This is the only acceptable usage of an underscore in a variable
name. Member variables declared public or protected
may never start with an underscore. The var construct is not
permitted.
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.
Properties
Properties are OOP enhancement provided by NObject. 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
Naming conventions:
- camelCase
- Try to use a verb or verb-object pair.
- If method returns boolean, try to prefix name with „is“, „can“, „has“.
- Names should 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 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.
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 four spaces
}
}
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.
Function and Method 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);
Extension Methods
Extension methods are OOP enhancement provided by NObject. They must follow
the same conventions as other methods, but they are declared in the global scope
and prefixed with {Class name}_prototype_. First parameter must
have object type hint.
Example:
function MyClass_prototype_newMethod(MyClass $obj)
Control 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. Any content within the braces must be indented four spaces.
if ($a != 2) {
$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;
}
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 four spaces.
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“.
Databases
- Use alphanumeric characters.
- Choose one way for all identifiers:
- use lowercase words and underscore
_to separate words - or use camelCaps
- use lowercase words and underscore
- Choose short, unambiguous names, using no more than one or two words.
- Avoid abbreviated, concatenated, or acronymic names.
Tables:
- Use plural table names.
- Prefix lookup tables with the name of the table they relate to (e.g.
order_statusororderStatus,order_type, etc.) - For junction table (which handle many to many relationships), concatenate
the names of the two
tables:
{linking-table}_2_{related-table}
Columns:
- Use singular column names.
- Don't prefix columns names with table name.
- The primary keys must have name
id.- If more than one field makes up the key, suffix all of them with
id(orpk?)
- If more than one field makes up the key, suffix all of them with
- Foreign key names should be the referenced table name in singular suffixed
with
id.- Makes the table to which they refer completely obvious.
- If there are multiple foreign keys referencing same table, prefix the
foreign key name with an appropriately descriptive adjective (e.g.
lead_person_id/leadPersonId,technical_person_id/technicalPersonId, etc. which transparently referenceidin thepersonstable).
- List the primary key first in a table, followed by foreign keys.
- Boolean fields should be given names like
is_deleted(orisDeleted),has_permission(orhasPermission). If the field holds date and/or time information, the worddateortimeshould appear somewhere in the field name.
Views:
- Follow the same rules that apply to naming tables with some exceptions:
- A view can be a combination of more tables based on a join condition, thus, effectively representing two entities. In this case, consider combining the names the base tables.
SQL coding style:
- Don't use the proprietary version destroying portability (
INSERT INTO ... VALUESvs.INSERT ... SET) - Format SQL to multiple lines:
SELECT *
FROM [customers]
WHERE [name] LIKE 'Peter%'
ORDER BY [name]
Myths of prefixing columns names with table name
- prevents field names clashing with reservered words → refering by tablename.fieldname prevents much better
- creates near unique field names, often simplifying query design and SQL coding → refering by tablename.fieldname does the same job
- maintains semantic transparency of field names when using table aliases (e.g. SELECT a.activity_name FROM activity a) → Definitely not. What about two same tables in join? Refering by alias.fieldname is right way.
Datatypes is MySQL:
- VARBINARY & BINARY implementation is stable since MySQL 5.0.19
- substitute boolean with „tinyint(1) NOT NULL DEFAULT ‚0‘“ (ENUM is not recommended)
- in non-strict mode ENUM can contain empty string



