mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Updated coding conventions for PSR-2
See https://github.com/silverstripe/silverstripe-framework/pull/6340 See https://github.com/silverstripe/silverstripe-framework/issues/6376
This commit is contained in:
parent
f39c4d94f2
commit
e1b84b3c8d
@ -9,360 +9,47 @@ and facilitate collaboration by making code more consistent and readable.
|
||||
|
||||
If you are unsure about a specific standard, imitate existing SilverStripe code.
|
||||
|
||||
## File Formatting
|
||||
## PSR-2
|
||||
|
||||
### Indentation
|
||||
Starting with SilverStripe 4.x, our goal is [PSR-2 Coding Standards](http://www.php-fig.org/psr/psr-2/) compliance.
|
||||
Since this affects existing APIs, some details like method casing will be iterated on in the next releases.
|
||||
For example, many static methods will need to be changed from lower underscore to lower camel casing.
|
||||
|
||||
## Spelling
|
||||
|
||||
Always use hard tabs rather then spaces for indentation, with one tab per nesting level.
|
||||
All symbols and documentation should use UK-English spelling (e.g. "behaviour" instead of "behavior"),
|
||||
except when necessitated by third party conventions (e.g using PHP's `Serializable` interface).
|
||||
|
||||
### Maximum Line Length
|
||||
## Configuration Variables
|
||||
|
||||
The target line length is 100 columns with tabs being treated as four columns,
|
||||
meaning developers should strive keep each line of their code
|
||||
under 80 columns where possible and practical.
|
||||
However, longer lines are acceptable in some circumstances.
|
||||
The maximum length of any line of PHP code is 120 columns.
|
||||
|
||||
### Line Termination
|
||||
|
||||
Line termination follows the Unix text file convention. Lines must end with a single linefeed (LF) character.
|
||||
Linefeed characters are represented as ordinal 10, or hexadecimal 0x0A.
|
||||
Note: Do not use carriage returns (CR) as is the convention in Apple OS's (0x0D) or the carriage return -
|
||||
linefeed combination (CRLF) as is standard for the Windows OS (0x0D, 0x0A).
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
Class, function, variable and constant names may only contain alphanumeric characters and underscores.
|
||||
|
||||
### Classes
|
||||
|
||||
Class and filenames are in `UpperCamelCase` format:
|
||||
SilverStripe's [Config API]() can read its defaults from variables declared as `private static` on classes.
|
||||
As opposed to other variables, these should be declared as lower case with underscores.
|
||||
|
||||
:::php
|
||||
class MyClass {}
|
||||
|
||||
If a class name is comprised of more than one word, the first letter of each
|
||||
new word must be capitalized. Successive capitalized letters are used in
|
||||
acronyms, e.g. a class `XMLImporter` is used while `XmlImporter` is not.
|
||||
|
||||
### Methods
|
||||
|
||||
Static methods should be in `lowercase_with_underscores()` format:
|
||||
|
||||
:::php
|
||||
public static function my_static_method() {}
|
||||
|
||||
Action handlers on controllers should be in `completelylowercase()` format.
|
||||
This is because they go into the controller URL in the same format (eg, `home/successfullyinstalled`).
|
||||
Method names are allowed to contain underscores here, in order to allow URL parts with dashes
|
||||
(`mypage\my-action` gets translated to `my_action()` automatically).
|
||||
|
||||
:::php
|
||||
public function mycontrolleraction() {}
|
||||
|
||||
Object methods that will be callable from templates should be in `$this->UpperCamelCase()` format.
|
||||
Alternatively, `$this->getUpperCamelCase()` will work the same way in templates -
|
||||
you can access both coding styles as `$UpperCamelCase`.
|
||||
|
||||
Other instance methods should be in `$this->lowerCamelCase()` format:
|
||||
|
||||
:::php
|
||||
public function myInstanceMethod() {}
|
||||
|
||||
Methods inside classes must always declare their visibility by using one of the private, protected, or public modifiers.
|
||||
|
||||
### Variables
|
||||
|
||||
Static variables should be `self::$lowercase_with_underscores`
|
||||
|
||||
:::php
|
||||
self::$my_static_variable = 'foo';
|
||||
|
||||
Member variables should be `$this->lowerCamelCase`
|
||||
|
||||
:::php
|
||||
$this->myMemberVariable = 'foo';
|
||||
|
||||
Member variables always declare their visibility by using one of the private, protected, or public modifiers
|
||||
|
||||
### Constants
|
||||
|
||||
All letters used in a constant name must be capitalized,
|
||||
while all words in a constant name must be separated by underscore characters.
|
||||
|
||||
:::php
|
||||
const INTEREST_RATE = 0.19;
|
||||
|
||||
define('INTEREST_RATE', 0.19);
|
||||
|
||||
Constants must be defined as class members with the `const` modifier.
|
||||
Defining constants in the global scope with the `define` function is permitted but strongly discouraged.
|
||||
|
||||
### File Naming and Directory Structure
|
||||
|
||||
Classes need to be in a file of the same name. Multiple classes are allowed to be contained in one file,
|
||||
as long as the prefix of the class equals the filename, and is separated by an underscore from the remaining name.
|
||||
For example `MyClass` and `MyClass_Controller` will both need to be placed into `MyClass.php`.
|
||||
|
||||
Example: `mysite/code/MyClass.php`
|
||||
|
||||
:::php
|
||||
<?php
|
||||
|
||||
class MyClass {}
|
||||
|
||||
class MyClass_Controller {}
|
||||
|
||||
class MyClass_OtherRelatedClass {}
|
||||
|
||||
To help with namespacing common class names (like Database) it is recommended to use a prefix convention `SS_ClassName` but the filename will remain `ClassName.php`.
|
||||
|
||||
See [directory structure](directory_structure) for more information.
|
||||
|
||||
## Coding Style
|
||||
|
||||
### PHP Code Declaration
|
||||
|
||||
PHP code must always be delimited by the full-form, standard PHP tags:
|
||||
|
||||
:::php
|
||||
<?php
|
||||
|
||||
|
||||
Short tags are never allowed. For files containing only PHP code, the closing tag must always be omitted.
|
||||
It is not required by PHP, and omitting it prevents the accidental injection of trailing white space into the response.
|
||||
|
||||
Files must end with an empty new line. This prevents problems arising from the end-of-file marker appearing where other
|
||||
white space is expected.
|
||||
|
||||
### Strings
|
||||
|
||||
#### String Literals
|
||||
|
||||
When a string is literal (contains no variable substitutions), the apostrophe or "single quote" should always be used to demarcate the string:
|
||||
|
||||
:::php
|
||||
$a = 'Example String';
|
||||
|
||||
#### String Literals Containing Apostrophes
|
||||
|
||||
When a literal string itself contains apostrophes, it is permitted to demarcate the string with quotation marks or "double quotes".
|
||||
|
||||
:::php
|
||||
$greeting = "They said 'hello'";
|
||||
|
||||
This syntax is preferred over escaping apostrophes as it is much easier to read.
|
||||
|
||||
#### String Substitution
|
||||
|
||||
Variable substitution is permitted using either of these forms:
|
||||
|
||||
:::php
|
||||
$greeting = "Hello $name, welcome back!";
|
||||
$greeting = "Hello {$name}, welcome back!";
|
||||
|
||||
For consistency, placing the dollar sign outside of the brackets is not permitted:
|
||||
|
||||
:::php
|
||||
$greeting = "Hello ${name}, welcome back!";
|
||||
|
||||
#### String Concatentation
|
||||
|
||||
Strings must be concatenated using the "." operator. A space must always be added before and after the "." operator to improve readability:
|
||||
|
||||
:::php
|
||||
$copyright = 'SilverStripe Ltd (' . $year . ')';
|
||||
|
||||
When concatenating strings with the "." operator, it is encouraged to break the statement into multiple lines to improve readability.
|
||||
In these cases, each successive line should be padded with white space such that the "."; operator is aligned under the "=" operator:
|
||||
|
||||
:::php
|
||||
$sql = 'SELECT "ID", "Name" FROM "Person" '
|
||||
. 'WHERE "Name" = \'Susan\' '
|
||||
. 'ORDER BY "Name" ASC ';
|
||||
|
||||
### Arrays
|
||||
|
||||
#### Numerically Indexed Arrays
|
||||
|
||||
Negative numbers are not permitted as indices.
|
||||
|
||||
An indexed array may start with any non-negative number, however all base indices besides 0 are discouraged.
|
||||
When declaring indexed arrays with the Array function, a trailing space must be added after each comma delimiter to improve readability:
|
||||
|
||||
:::php
|
||||
$sampleArray = array(1, 2, 3, 'Zend', 'Studio');
|
||||
|
||||
It is permitted to declare multi-line indexed arrays using the "array" construct.
|
||||
In this case, each successive line must be padded with spaces such that beginning of each line is aligned:
|
||||
|
||||
:::php
|
||||
$sampleArray = array(1, 2, 3, 'Zend', 'Studio',
|
||||
$a, $b, $c,
|
||||
56.44, $d, 500);
|
||||
|
||||
Alternately, the initial array item may begin on the following line.
|
||||
If so, it should be padded at one indentation level greater than the line containing the array declaration,
|
||||
and all successive lines should have the same indentation;
|
||||
the closing paren should be on a line by itself at the same indentation level as the line containing the array declaration:
|
||||
|
||||
:::php
|
||||
$sampleArray = array(
|
||||
1, 2, 3, 'Zend', 'Studio',
|
||||
$a, $b, $c,
|
||||
56.44, $d, 500,
|
||||
);
|
||||
|
||||
When using this latter declaration, we encourage using a trailing comma for the last item in the array;
|
||||
this minimizes the impact of adding new items on successive lines, and helps to ensure no parse errors occur due to a missing comma.
|
||||
|
||||
#### Associative Arrays
|
||||
|
||||
When declaring associative arrays with the `array` construct, breaking the statement into multiple lines is encouraged.
|
||||
In this case, each successive line must be padded with white space such that both the keys and the values are aligned:
|
||||
|
||||
:::php
|
||||
$sampleArray = array('firstKey' => 'firstValue',
|
||||
'secondKey' => 'secondValue');
|
||||
|
||||
Alternately, the initial array item may begin on the following line.
|
||||
If so, it should be padded at one indentation level greater than the line containing the array declaration,
|
||||
and all successive lines should have the same indentation; the closing paren should be on a line by itself at the
|
||||
same indentation level as the line containing the array declaration.
|
||||
For readability, the various "=>" assignment operators should be padded such that they align.
|
||||
|
||||
:::php
|
||||
$sampleArray = array(
|
||||
'firstKey' => 'firstValue',
|
||||
'secondKey' => 'secondValue',
|
||||
);
|
||||
|
||||
### Function and Method Declaration
|
||||
|
||||
No method or function invocation is allowed to have spaces directly
|
||||
before or after the opening parathesis, as well as no space before the closing parenthesis.
|
||||
|
||||
:::php
|
||||
public function foo($arg1, $arg2) {} // good
|
||||
public function foo ( $arg1, $arg2 ) {} // bad
|
||||
|
||||
Keep the opening brace on the same line as the statement.
|
||||
|
||||
:::php
|
||||
// good
|
||||
public function foo() {
|
||||
// ...
|
||||
}
|
||||
|
||||
// bad
|
||||
public function bar()
|
||||
class MyClass
|
||||
{
|
||||
// ...
|
||||
private static $my_config_variable = 'foo';
|
||||
}
|
||||
|
||||
In cases where the argument list exceeds the maximum line length, you may introduce line breaks.
|
||||
Additional arguments to the function or method must be indented one additional level beyond the function or method declaration.
|
||||
A line break should then occur before the closing argument paren,
|
||||
which should then be placed on the same line as the opening brace of the function
|
||||
or method with one space separating the two, and at the same indentation level as the function or method declaration.
|
||||
|
||||
:::php
|
||||
public function bar($arg1, $arg2, $arg3,
|
||||
$arg4, $arg5, $arg6
|
||||
) {
|
||||
// indented code
|
||||
}
|
||||
|
||||
Function and method arguments should be separated by a single trailing space after the comma delimiter,
|
||||
apart from the last argument.
|
||||
|
||||
### Control Structures
|
||||
|
||||
#### if/else/elseif
|
||||
|
||||
No control structure is allowed to have spaces directly
|
||||
before or after the opening parenthesis, as well as no space before the closing parenthesis.
|
||||
|
||||
The opening brace and closing brace are written on the same line as the conditional statement.
|
||||
Any content within the braces must be indented using a tab.
|
||||
|
||||
:::php
|
||||
if($a != 2) {
|
||||
$a = 2;
|
||||
}
|
||||
|
||||
If the conditional statement causes the line length to exceed the maximum line length and has several clauses,
|
||||
you may break the conditional into multiple lines. In such a case, break the line prior to a logic operator,
|
||||
and pad the line such that it aligns under the first character of the conditional clause.
|
||||
The closing paren in the conditional will then be placed on a line with the opening brace,
|
||||
with one space separating the two, at an indentation level equivalent to the opening control statement.
|
||||
|
||||
:::php
|
||||
if(($a == $b)
|
||||
&& ($b == $c)
|
||||
|| (Foo::CONST == $d)
|
||||
) {
|
||||
$a = $d;
|
||||
}
|
||||
|
||||
The intention of this latter declaration format is to prevent issues when adding or removing clauses
|
||||
from the conditional during later revisions. For `if` statements that include `elseif` or `else`,
|
||||
the formatting conventions are similar to the `if` construct.
|
||||
The following examples demonstrate proper formatting for `if` statements with `else` and/or `elseif` constructs:
|
||||
|
||||
:::php
|
||||
if($a != 2) {
|
||||
$a = 2;
|
||||
} elseif($a == 3) {
|
||||
$a = 4;
|
||||
} else {
|
||||
$a = 7;
|
||||
}
|
||||
|
||||
Statements with `if` can be written without braces on a single line as the block, as long as no `else` statement exists.
|
||||
|
||||
:::php
|
||||
// good
|
||||
if($a == $b) doThis();
|
||||
|
||||
// bad
|
||||
if($a == $b) doThis();
|
||||
else doThat();
|
||||
|
||||
#### Prefer identical (===) comparisons over equality (==)
|
||||
## Prefer identical (===) comparisons over equality (==)
|
||||
|
||||
Where possible, use type-strict identical comparisons instead of loosely typed equality comparisons.
|
||||
Read more in the PHP documentation for [comparison operators](http://php.net/manual/en/language.operators.comparison.php) and [object comparison](http://php.net/manual/en/language.oop5.object-comparison.php).
|
||||
|
||||
:::php
|
||||
// good - only need to cast to (int) if $a might not already be an int
|
||||
if((int)$a === 100) doThis();
|
||||
if ((int)$a === 100) {
|
||||
doThis();
|
||||
}
|
||||
|
||||
// bad
|
||||
if($a == 100) doThis();
|
||||
|
||||
#### switch
|
||||
|
||||
All content within the "switch" statement must be indented using tabs.
|
||||
Content under each "case" statement must be indented using an additional tab.
|
||||
|
||||
:::php
|
||||
switch($numPeople) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if ($a == 100) {
|
||||
doThis();
|
||||
}
|
||||
|
||||
The construct `default` should never be omitted from a switch statement.
|
||||
|
||||
#### for/foreach/while
|
||||
|
||||
Loop constructs follow the same principles as "Control Structures: if/else/elseif".
|
||||
|
||||
### Separation of Logic and Presentation
|
||||
## Separation of Logic and Presentation
|
||||
|
||||
Try to avoid using PHP's ability to mix HTML into the code.
|
||||
|
||||
@ -414,20 +101,24 @@ Example:
|
||||
*
|
||||
* @package custom
|
||||
*/
|
||||
class MyClass extends Class {
|
||||
class MyClass extends Class
|
||||
{
|
||||
|
||||
/**
|
||||
* My Method.
|
||||
* This method returns something cool. {@link MyParentMethod} has other cool stuff in it.
|
||||
*
|
||||
* @param string $colour The colour of cool things that you want
|
||||
* @return DataList A list of everything cool
|
||||
*/
|
||||
public function myMethod($foo) {}
|
||||
/**
|
||||
* My Method.
|
||||
* This method returns something cool. {@link MyParentMethod} has other cool stuff in it.
|
||||
*
|
||||
* @param string $colour The colour of cool things that you want
|
||||
* @return DataList A list of everything cool
|
||||
*/
|
||||
public function myMethod($foo)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
### Class Member Ordering
|
||||
## Class Member Ordering
|
||||
|
||||
Put code into the classes in the following order (where applicable).
|
||||
|
||||
@ -441,7 +132,7 @@ Put code into the classes in the following order (where applicable).
|
||||
* Template data-access methods (methods that will be called by a `$MethodName` or `<% loop $MethodName %>` construct in a template somewhere)
|
||||
* Object methods
|
||||
|
||||
### SQL Format
|
||||
## SQL Format
|
||||
|
||||
If you have to use raw SQL, make sure your code works across databases. Make sure you escape your queries like below,
|
||||
with the column or table name escaped with double quotes as below.
|
||||
@ -459,15 +150,10 @@ are single quoted.
|
||||
|
||||
Use [ANSI SQL](http://en.wikipedia.org/wiki/SQL#Standardization) format where possible.
|
||||
|
||||
### Secure Development
|
||||
## Secure Development
|
||||
|
||||
See [security](/developer_guides/security) for conventions related to handing security permissions.
|
||||
|
||||
## License
|
||||
|
||||
Parts of these coding conventions were adapted from [Zend Framework](http://framework.zend.com/manual/en/coding-standard.overview.html),
|
||||
which are licensed under BSD (see [license](http://framework.zend.com/license)).
|
||||
|
||||
## Related
|
||||
|
||||
* [JavaScript Coding Conventions](/contributing/javascript_coding_conventions)
|
||||
|
Loading…
Reference in New Issue
Block a user