Yii2 Core framework code style ============================== The following code style is used for Yii 2.x core and official extensions development. If you want to pull-request code into the core, consider using it. We aren't forcing you to use this code style for your application. Feel free to choose what suits you better. You can get a config for CodeSniffer here: https://github.com/yiisoft/yii2-coding-standards 1. Overview ----------- - Files MUST use either `` or ``. - Do not add trailing spaces to the end of the lines. - Any file that contains PHP code should end with the extension `.php`. ### 2.2. Character Encoding PHP code MUST use only UTF-8 without BOM. 3. Class Names -------------- Class names MUST be declared in `StudlyCaps`. For example, `Controller`, `Model`. 4. Classes ---------- The term "class" refers to all classes and interfaces here. - Classes should be named using `CamelCase`. - The brace should always be written on the line underneath the class name. - Every class must have a documentation block that conforms to the PHPDoc. - All code in a class must be indented with a single tab. - There should be only one class in a single PHP file. - All classes should be namespaced. - Class name should match file name. Class namespace should match directory structure. ```php /** * Documentation */ class MyClass extends \yii\Object implements MyInterface { // code } ``` ### 4.1. Constants Class constants MUST be declared in all upper case with underscore separators. For example: ```php 'Yii', 'options' => ['usePHP' => true], ]; ``` Changing type of an existing variable is considered as a bad practice. Try not to write such code unless it is really necessary. ```php public function save(Transaction $transaction, $argument2 = 100) { $transaction = new Connection; // bad $argument2 = 200; // good } ``` ### 5.2 Strings - If string doesn't contain variables or single quotes, use single quotes. ```php $str = 'Like this.'; ``` - If string contains single quotes you can use double quotes to avoid extra escaping. #### Variable substitution ```php $str1 = "Hello $username!"; $str2 = "Hello {$username}!"; ``` The following is not permitted: ```php $str3 = "Hello ${username}!"; ``` #### Concatenation Add spaces around dot when concatenating strings: ```php $name = 'Yii' . ' Framework'; ``` When string is long format is the following: ```php $sql = "SELECT *" . "FROM `post` " . "WHERE `id` = 121 "; ``` ### 5.3 arrays For arrays we're using PHP 5.3 short array syntax. #### Numerically indexed - Do not use negative numbers as array indexes. Use the following formatting when declaring array: ```php $arr = [3, 14, 15, 'Yii', 'Framework']; ``` If there are too many elements for a single line: ```php $arr = [ 3, 14, 15, 92, 6, $test, 'Yii', 'Framework', ]; ``` #### Associative Use the following format for associative arrays: ```php $config = [ 'name' => 'Yii', 'options' => ['usePHP' => true], ]; ``` ### 5.4 control statements - Control statement condition must have single space before and after parenthesis. - Operators inside of parenthesis should be separated by spaces. - Opening brace is on the same line. - Closing brace is on a new line. - Always use braces for single line statements. ```php if ($event === null) { return new Event(); } elseif ($event instanceof CoolEvent) { return $event->instance(); } else { return null; } // the following is NOT allowed: if(!$model && null === $event) throw new Exception('test'); ``` #### switch Use the following formatting for switch: ```php switch ($this->phpType) { case 'string': $a = (string)$value; break; case 'integer': case 'int': $a = (integer)$value; break; case 'boolean': $a = (boolean)$value; break; default: $a = null; } ``` ### 5.5 function calls ```php doIt(2, 3); doIt(['a' => 'b']); doIt('a', [ 'a' => 'b', 'c' => 'd', ]); ``` ### 5.6 Anonymous functions (lambda) declarations Note space between `function`/`use` tokens and open parenthesis: ```php // good $n = 100; $sum = array_reduce($numbers, function ($r, $x) use ($n) { $this->doMagic(); $r += $x * $n; return $r; }); // bad $n = 100; $mul = array_reduce($numbers, function($r, $x) use($n) { $this->doMagic(); $r *= $x * $n; return $r; }); ``` Documentation ------------- - Refer ot [phpDoc](http://phpdoc.org/) for documentation syntax. - Code without documentation is not allowed. - All class files must contain a "file-level" docblock at the top of each file and a "class-level" docblock immediately above each class. - There is no need to use `@return` if method does return nothing. - All virtual properties in classes that extend from `yii\base\Object` are documented with an `@property` tag in the class doc block. These annotations are automatically generated from the `@return` or `@param` tag in the corresponding getter or setter by running `./build php-doc` in the build directory. You may add an `@property` tag to the getter or setter to explicitly give a documentation message for the property introduced by these methods when description differs from what is stated in `@return`. Here is an example: ```php * @since 2.0 */ class Component extends \yii\base\Object ``` #### Function / method ```php /** * Returns the list of attached event handlers for an event. * You may manipulate the returned [[Vector]] object by adding or removing handlers. * For example, * * ~~~ * $component->getEventHandlers($eventName)->insertAt(0, $eventHandler); * ~~~ * * @param string $name the event name * @return Vector list of attached event handlers for the event * @throws Exception if the event is not defined */ public function getEventHandlers($name) { if (!isset($this->_e[$name])) { $this->_e[$name] = new Vector; } $this->ensureBehaviors(); return $this->_e[$name]; } ``` #### Markdown As you can see in the examples above we use markdown to format the phpDoc comments. There is additional syntax for cross linking between classes, methods and properties in the documentation: - `'[[canSetProperty]] ` will create a link to the `canSetProperty` method or property of the same class. - `'[[Component::canSetProperty]]` will create a link to `canSetProperty` method of the class `Component` in the same namespace. - `'[[yii\base\Component::canSetProperty]]` will create a link to `canSetProperty` method of the class `Component` in namespace `yii\base`. - `'[[Component]]` will create a link to the `Component` class in the same namespace. Adding namespace to the class name is also possible here. To give one of the above mentioned links another label than the class or method name you can use the syntax shown in the following example: ``` ... as displayed in the [[header|header cell]]. ``` The part before the | is the method, property or class reference while the part after | is the link label. #### Comments - One-line comments should be started with `//` and not `#`. - One-line comment should be on its own line. Additional rules ---------------- ### `=== []` vs `empty()` Use `empty()` where possible. ### multiple return points Return early when conditions nesting starts to get cluttered. If the method is short it doesn't matter. ### `self` vs. `static` Always use `static` except the following cases: - accessing constants MUST be done via `self`: `self::MY_CONSTANT` - accessing private static properties MUST be done via `self`: `self::$_events` - It is allowed to use `self` for recursion to call current implementation again instead of extending classes implementation. ### value for "don't do something" Properties allowing to configure component not to do something should accept value of `false`. `null`, `''`, or `[]` should not be assumed as such. ### Directory/namespace names - use lower case - use plural form for nouns which represent objects (e.g. validators) - use singular form for names representing relevant functionality/features (e.g. web)