mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 02:28:35 +08:00 
			
		
		
		
	 c3ca164be2
			
		
	
	c3ca164be2
	
	
	
		
			
			* Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals) * Update links (internals)
		
			
				
	
	
		
			508 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			508 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| Yii 2 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
 | |
| 
 | |
| Overall we're using [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
 | |
| compatible style so everything that applies to
 | |
| [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) is applied to our code
 | |
| style as well.
 | |
| 
 | |
| - Files MUST use either `<?php` or `<?=` tags.
 | |
| - There should be a newline at the end of file.
 | |
| - Files MUST use only UTF-8 without BOM for PHP code.
 | |
| - Code MUST use 4 spaces for indenting, not tabs.
 | |
| - Class names MUST be declared in `StudlyCaps`.
 | |
| - Class constants MUST be declared in all upper case with underscore separators.
 | |
| - Method names MUST be declared in `camelCase`.
 | |
| - Property names MUST be declared in `camelCase`.
 | |
| - Property names MUST start with an initial underscore if they are private.
 | |
| - Always use `elseif` instead of `else if`.
 | |
| 
 | |
| ## 2. Files
 | |
| 
 | |
| ### 2.1. PHP Tags
 | |
| 
 | |
| - PHP code MUST use `<?php ?>` or `<?=` tags; it MUST NOT use the other tag variations such as `<?`.
 | |
| - In case file contains PHP only it should not have trailing `?>`.
 | |
| - 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 `StudlyCase`.
 | |
| - 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 4 spaces.
 | |
| - 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\base\BaseObject implements MyInterface
 | |
| {
 | |
|     // code
 | |
| }
 | |
| ```
 | |
| 
 | |
| ### 4.1. Constants
 | |
| 
 | |
| Class constants MUST be declared in all upper case with underscore separators.
 | |
| For example:
 | |
| 
 | |
| ```php
 | |
| <?php
 | |
| class Foo
 | |
| {
 | |
|     const VERSION = '1.0';
 | |
|     const DATE_APPROVED = '2012-06-01';
 | |
| }
 | |
| ```
 | |
| ### 4.2. Properties
 | |
| 
 | |
| - When declaring public class members specify `public` keyword explicitly.
 | |
| - Public and protected variables should be declared at the top of the class before any method declarations.
 | |
|   Private variables should also be declared at the top of the class but may be added right before the methods
 | |
|   that are dealing with them in cases where they are only related to a small subset of the class methods.
 | |
| - The order of property declaration in a class should be ascending based on their visibility: from public over protected to private.
 | |
| - There are no strict rules for ordering properties that have the same visibility.
 | |
| - For better readability there should be no blank lines between property declarations and two blank lines
 | |
|   between property and method declaration sections. One blank line should be added between the different visibility groups.
 | |
| - Private variables should be named like `$_varName`.
 | |
| - Public class members and standalone variables should be named using `$camelCase`
 | |
|   with first letter lowercase.
 | |
| - Use descriptive names. Variables such as `$i` and `$j` are better not to be used.
 | |
| 
 | |
| For example:
 | |
| 
 | |
| ```php
 | |
| <?php
 | |
| class Foo
 | |
| {
 | |
|     public $publicProp1;
 | |
|     public $publicProp2;
 | |
| 
 | |
|     protected $protectedProp;
 | |
| 
 | |
|     private $_privateProp;
 | |
| 
 | |
| 
 | |
|     public function someMethod()
 | |
|     {
 | |
|         // ...
 | |
|     }
 | |
| }
 | |
| ```
 | |
| 
 | |
| ### 4.3. Methods
 | |
| 
 | |
| - Functions and methods should be named using `camelCase` with first letter lowercase.
 | |
| - Name should be descriptive by itself indicating the purpose of the function.
 | |
| - Class methods should always declare visibility using `private`, `protected` and
 | |
|   `public` modifiers. `var` is not allowed.
 | |
| - Opening brace of a function should be on the line after the function declaration.
 | |
| 
 | |
| ```php
 | |
| /**
 | |
|  * Documentation
 | |
|  */
 | |
| class Foo
 | |
| {
 | |
|     /**
 | |
|      * Documentation
 | |
|      */
 | |
|     public function bar()
 | |
|     {
 | |
|         // code
 | |
|         return $value;
 | |
|     }
 | |
| }
 | |
| ```
 | |
| 
 | |
| ### 4.4 PHPDoc blocks
 | |
| 
 | |
|  - `@param`, `@var`, `@property` and `@return` must declare types as `bool`, `int`, `string`, `array` or `null`.
 | |
|    You can use a class names as well such as `Model` or `ActiveRecord`.
 | |
|  - For a typed arrays use `ClassName[]`.
 | |
|  - The first line of the PHPDoc must describe the purpose of the method.
 | |
|  - If method checks something (`isActive`, `hasClass`, etc) the first line should start with `Checks whether`.
 | |
|  - `@return` should explicitly describe what exactly will be returned.
 | |
| 
 | |
| ```php
 | |
| /**
 | |
|  * Checks whether the IP is in subnet range
 | |
|  *
 | |
|  * @param string $ip an IPv4 or IPv6 address
 | |
|  * @param int $cidr the CIDR length
 | |
|  * @param string $range subnet in CIDR format e.g. `10.0.0.0/8` or `2001:af::/64`
 | |
|  * @return bool whether the IP is in subnet range
 | |
|  */
 | |
|  private function inRange($ip, $cidr, $range)
 | |
|  {
 | |
|    // ...
 | |
|  }
 | |
| ```
 | |
| 
 | |
| ### 4.5 Constructors
 | |
| 
 | |
| - `__construct` should be used instead of PHP 4 style constructors.
 | |
| 
 | |
| ## 5 PHP
 | |
| 
 | |
| ### 5.1 Types
 | |
| 
 | |
| - All PHP types and values should be used lowercase. That includes `true`, `false`, `null` and `array`.
 | |
| 
 | |
| 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.4 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();
 | |
| }
 | |
| if ($event instanceof CoolEvent) {
 | |
|     return $event->instance();
 | |
| }
 | |
| return null;
 | |
| 
 | |
| 
 | |
| // the following is NOT allowed:
 | |
| if (!$model && null === $event)
 | |
|     throw new Exception('test');
 | |
| ```
 | |
| 
 | |
| Prefer avoiding `else` after `return` where it makes sense.
 | |
| Use [guard conditions](https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html).
 | |
| 
 | |
| ```php
 | |
| $result = $this->getResult();
 | |
| if (empty($result)) {
 | |
|     return true;
 | |
| } else {
 | |
|     // process result
 | |
| }
 | |
| ```
 | |
| 
 | |
| is better as
 | |
| 
 | |
| ```php
 | |
| $result = $this->getResult();
 | |
| if (empty($result)) {
 | |
|    return true;
 | |
| }
 | |
| 
 | |
| // process result
 | |
| ```
 | |
| 
 | |
| #### switch
 | |
| 
 | |
| Use the following formatting for switch:
 | |
| 
 | |
| ```php
 | |
| switch ($this->phpType) {
 | |
|     case 'string':
 | |
|         $a = (string) $value;
 | |
|         break;
 | |
|     case 'integer':
 | |
|     case 'int':
 | |
|         $a = (int) $value;
 | |
|         break;
 | |
|     case 'boolean':
 | |
|         $a = (bool) $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 to [phpDoc](https://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\BaseObject`
 | |
|   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
 | |
|     <?php
 | |
|     /**
 | |
|      * Returns the errors for all attribute or a single attribute.
 | |
|      * @param string $attribute attribute name. Use null to retrieve errors for all attributes.
 | |
|      * @property array An array of errors for all attributes. Empty array is returned if no error.
 | |
|      * The result is a two-dimensional array. See [[getErrors()]] for detailed description.
 | |
|      * @return array errors for all attributes or the specified attribute. Empty array is returned if no error.
 | |
|      * Note that when returning errors for all attributes, the result is a two-dimensional array, like the following:
 | |
|      * ...
 | |
|      */
 | |
|     public function getErrors($attribute = null)
 | |
|   ```
 | |
| 
 | |
| #### File
 | |
| 
 | |
| ```php
 | |
| <?php
 | |
| /**
 | |
|  * @link https://www.yiiframework.com/
 | |
|  * @copyright Copyright (c) 2008 Yii Software LLC
 | |
|  * @license https://www.yiiframework.com/license/
 | |
|  */
 | |
| ```
 | |
| 
 | |
| #### Class
 | |
| 
 | |
| ```php
 | |
| /**
 | |
|  * Component is the base class that provides the *property*, *event* and *behavior* features.
 | |
|  *
 | |
|  * @include @yii/docs/base-Component.md
 | |
|  *
 | |
|  * @author Qiang Xue <qiang.xue@gmail.com>
 | |
|  * @since 2.0
 | |
|  */
 | |
| class Component extends \yii\base\BaseObject
 | |
| ```
 | |
| 
 | |
| 
 | |
| #### 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.
 | |
| 
 | |
| It is also possible to link to the Guide using the following syntax:
 | |
| 
 | |
| ```markdown
 | |
| [link to guide](guide:file-name.md)
 | |
| [link to guide](guide:file-name.md#subsection)
 | |
| ```
 | |
| 
 | |
| 
 | |
| #### 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 method calls where it makes sense such as recursive call to current implementation 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)
 | |
| - prefer single word namespaces
 | |
| - if single word isn't suitable, use camelCase
 | |
| 
 |