2016-04-25 11:55:33 +02:00
# PHP Coding Conventions
2011-02-07 07:48:44 +01:00
This document provides guidelines for code formatting and documentation
to developers contributing to SilverStripe. It applies to all PHP files
2016-04-25 11:55:33 +02:00
in the `framework/` and `cms/` modules, as well as any supported additional modules.
2011-02-07 07:48:44 +01:00
Coding standards are an important aspect for every software project,
and facilitate collaboration by making code more consistent and readable.
If you are unsure about a specific standard, imitate existing SilverStripe code.
2016-12-08 23:59:01 +01:00
## PSR-2
2011-02-07 07:48:44 +01:00
2016-12-08 23:59:01 +01:00
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
2011-02-07 07:48:44 +01:00
2016-12-08 23:59:01 +01:00
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).
2011-02-07 07:48:44 +01:00
2016-12-08 23:59:01 +01:00
## Configuration Variables
2011-02-07 07:48:44 +01:00
2016-12-08 23:59:01 +01:00
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.
2011-02-07 07:48:44 +01:00
:::php
2016-12-08 23:59:01 +01:00
class MyClass
2011-02-07 07:48:44 +01:00
{
2016-12-08 23:59:01 +01:00
private static $my_config_variable = 'foo';
2011-02-07 07:48:44 +01:00
}
2016-12-08 23:59:01 +01:00
## Prefer identical (===) comparisons over equality (==)
2016-11-01 06:12:11 +01:00
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
2016-12-08 23:59:01 +01:00
if ((int)$a === 100) {
doThis();
}
2016-11-01 06:12:11 +01:00
// bad
2016-12-08 23:59:01 +01:00
if ($a == 100) {
doThis();
2011-02-07 07:48:44 +01:00
}
2016-12-08 23:59:01 +01:00
## Separation of Logic and Presentation
2011-02-07 07:48:44 +01:00
Try to avoid using PHP's ability to mix HTML into the code.
:::php
// PHP code
2012-01-30 23:13:42 +01:00
public function getTitle() {
2016-04-25 11:55:33 +02:00
return "< h2 > Bad Example< / h2 > ";
2011-02-07 07:48:44 +01:00
}
2016-04-25 11:55:33 +02:00
2011-02-07 07:48:44 +01:00
// Template code
$Title
Better: Keep HTML in template files:
:::php
// PHP code
2012-01-30 23:13:42 +01:00
public function getTitle() {
2011-02-07 07:48:44 +01:00
return "Better Example";
}
2016-04-25 11:55:33 +02:00
2011-02-07 07:48:44 +01:00
// Template code
< h2 > $Title< / h2 >
## Comments
Use [phpdoc ](http://phpdoc.org/ ) syntax before each definition (see [tutorial ](http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.quickstart.pkg.html )
and [tag overview ](http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_tags.pkg.html )).
* All class definitions and PHP files should have `@package` and `@subpackage` .
* Methods should include at least `@param` and `@return` .
2016-04-25 11:55:33 +02:00
* Include a blank line after the description.
2011-02-07 07:48:44 +01:00
* Use `{@link MyOtherClass}` and `{@link MyOtherClass->otherMethod}` for inline references.
* Denote preformatted code examples in `<code></code>` blocks.
* Always start block-level comments containing phpdoc with two asterisks (`/** ... */`).
Example:
:::php
2016-04-25 11:55:33 +02:00
/**
2011-02-07 07:48:44 +01:00
* My short description for this class.
* My longer description with
* multiple lines and richer formatting.
2016-04-25 11:55:33 +02:00
*
2011-02-07 07:48:44 +01:00
* Usage:
* < code >
* $c = new MyClass();
* $c->myMethod();
* </ code >
2016-04-25 11:55:33 +02:00
*
2011-02-07 07:48:44 +01:00
* @package custom
*/
2016-12-08 23:59:01 +01:00
class MyClass extends Class
{
2016-04-25 11:55:33 +02:00
2016-12-08 23:59:01 +01:00
/**
* 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)
{
// ...
}
2016-04-25 11:55:33 +02:00
2011-02-07 07:48:44 +01:00
}
2016-04-25 11:55:33 +02:00
2016-12-08 23:59:01 +01:00
## Class Member Ordering
2011-02-07 07:48:44 +01:00
Put code into the classes in the following order (where applicable).
* Static variables
2012-01-30 23:13:42 +01:00
* Member variables
2011-02-07 07:48:44 +01:00
* Static methods
* Data-model definition static variables. (`$db`, `$has_one` , `$many_many` , etc)
* Commonly used methods like `getCMSFields()`
* Accessor methods (`getMyField()` and `setMyField()` )
* Controller action methods
2013-04-26 11:48:59 +02:00
* Template data-access methods (methods that will be called by a `$MethodName` or `<% loop $MethodName %>` construct in a template somewhere)
2011-02-07 07:48:44 +01:00
* Object methods
2016-12-08 23:59:01 +01:00
## SQL Format
2011-02-07 07:48:44 +01:00
2016-04-25 11:55:33 +02:00
If you have to use raw SQL, make sure your code works across databases. Make sure you escape your queries like below,
2013-06-21 00:32:08 +02:00
with the column or table name escaped with double quotes as below.
:::php
MyClass::get()->where(array("\"Score\" > ?" => 50));
It is preferable to use parameterised queries whenever necessary to provide conditions
to a SQL query, where values placeholders are each replaced with a single unquoted question mark.
If it's absolutely necessary to use literal values in a query make sure that values
are single quoted.
2011-02-07 07:48:44 +01:00
:::php
2012-06-23 00:32:43 +02:00
MyClass::get()->where("\"Title\" = 'my title'");
2011-02-07 07:48:44 +01:00
Use [ANSI SQL ](http://en.wikipedia.org/wiki/SQL#Standardization ) format where possible.
2016-12-08 23:59:01 +01:00
## Secure Development
2011-02-07 07:48:44 +01:00
2016-01-14 11:59:53 +01:00
See [security ](/developer_guides/security ) for conventions related to handing security permissions.
2011-02-07 07:48:44 +01:00
2012-05-16 11:38:20 +02:00
## Related
2016-06-03 00:53:35 +02:00
* [JavaScript Coding Conventions ](/contributing/javascript_coding_conventions )
2015-02-28 01:09:15 +01:00
* [Reference: CMS Architecture ](/developer_guides/customising_the_admin_interface/cms_architecture )