You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
478 lines
20 KiB
478 lines
20 KiB
9 years ago
|
Стиль кодирования Yii2 framework
|
||
|
==============================
|
||
|
|
||
|
Описанный ниже стиль кодирования используется при разработке ядра Yii 2.x и его официальных расширений. Если вы хотите участвовать в разработке фреймворка, постарайтесь придерживаться данного стиля. Мы не принуждаем вас использовать этот стиль при разработке ваших приложений с использованием Yii 2. В данном случае можете использовать тот стиль, который вам больше подходит.
|
||
|
|
||
|
Пример конфигурационного файла для CodeSniffer вы можете найти здесь: https://github.com/yiisoft/yii2-coding-standards
|
||
|
|
||
|
1. Обзор
|
||
|
-----------
|
||
|
|
||
|
В общем, мы используем совместимый со стандартом [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) стиль, так что все положения [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) вполне применимы к нашему стилю кодирования.
|
||
|
|
||
|
- ДОЛЖНЫ использоваться только открывающие теги `<?php` или `<?=`;
|
||
|
- В конце файла должна быть пустая строка;
|
||
|
- Файлы PHP кодом ДОЛЖНЫ содержать только символы в кодировке UTF-8 без BOM;
|
||
|
- Для выравнивания кода НУЖНО использовать 4 пробела вместо табуляции;
|
||
|
- Имена классов ДОЛЖНЫ быть объявлены используя `StudlyCaps`;
|
||
|
- Константы класса ДОЛЖНЫ быть объявлены в верхнем регистре с подчеркиванием в качестве разделителей;
|
||
|
- Имена методов ДОЛЖНЫ быть объявлены используя `camelCase`;
|
||
|
- Имена свойств ДОЛЖНЫ быть объявлены используя `camelCase`;
|
||
|
- Имена свойств ДОЛЖНЫ начинаться с подчеркивания если они объявлены с использованием модификатора `private`;
|
||
|
- Всегда используйте `elseif` вместо `else if`.
|
||
|
|
||
|
2. Файлы
|
||
|
--------
|
||
|
|
||
|
### 2.1. Теги PHP
|
||
|
|
||
|
- В PHP коде ДОЛЖНЫ использоваться теги `<?php ?>` или `<?=`; НЕ ДОЛЖНЫ использоваться другие теги, такие как `<?`;
|
||
|
- Если файл содержит только PHP код, тогда закрывающий тег `?>` не нужен;
|
||
|
- Не добавляйте лишние пробелы в конец строки;
|
||
|
- Все файлы, содержащие PHP код, должны иметь расширение `.php`.
|
||
|
|
||
|
### 2.2. Кодировка символов
|
||
|
|
||
|
PHP код должен содержать только символы в кодировке UTF-8 без BOM.
|
||
|
|
||
|
3. Имена Классов
|
||
|
--------------
|
||
|
|
||
|
Имена классов ДОЛЖНЫ быть определены используя `StudlyCaps`. Например, `Controller`, `Model`.
|
||
|
|
||
|
4. Классы
|
||
|
----------
|
||
|
|
||
|
В данном случае, под классом подразумеваются все классы и интерфейсы.
|
||
|
|
||
|
- При именовании классов следует использовать `CamelCase`;
|
||
|
- Открывающая фигурная скобка всегда должна быть на следующей строке после имена класса;
|
||
|
- Все классы должны быть документированы в соответствии с PHPDoc;
|
||
|
- Весь код класса должен быть выровнен с использованием 4 пробелов;
|
||
|
- В одном PHP файле должен быть только один класс;
|
||
|
- Все классы должны использовать пространства имен;
|
||
|
- Имя класса должно совпадать с именем файла. Пространство имен класса должно соответствовать структуре каталогов.
|
||
|
|
||
|
```php
|
||
|
/**
|
||
|
* Документация
|
||
|
*/
|
||
|
class MyClass extends \yii\Object implements MyInterface
|
||
|
{
|
||
|
// код
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 4.1. Константы
|
||
|
|
||
|
Константы класса ДОЛЖНЫ быть объявлены в верхнем регистре с подчеркиванием в качестве разделителей.
|
||
|
Пример:
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
class Foo
|
||
|
{
|
||
|
const VERSION = '1.0';
|
||
|
const DATE_APPROVED = '2012-06-01';
|
||
|
}
|
||
|
```
|
||
|
### 4.2. Свойства
|
||
|
|
||
|
- При объявлении общедоступных (public) членов класса нужно использовать ключевое слово `public`;
|
||
|
- Общедоступные и защищенные (protected) переменные должны быть объявлены в начале класса, раньше объявления методов;
|
||
|
Закрытые (private) переменные, так же, должны быть объявлены в начале класса, но могут быть добавлены и непосредственно перед методами, использующими их, в случае, если эти переменные используются только небольшой частью методов класса;
|
||
|
- Порядок объявления свойств класса должен соответствовать их видимости: общедоступные, защищенные и закрытые;
|
||
|
- Ограничений на порядок свойств одной области видимости нет;
|
||
|
- Для улучшения читаемости, следует не оставлять пустых строк между объявлением свойств и оставлять две пустые строки между объявлениями переменных и методов. Между объявлениями свойств разной области видимости нужно должна быть добавлена одна пустая строка;
|
||
|
- Закрытые переменные должны иметь имя вида `$_varName`;
|
||
|
- Общедоступные члены класса и отдельные переменные должны использовать `$camelCase`
|
||
|
с первой буквой в нижнем регистре;
|
||
|
- Используйте понятные имена. Переменные вроде `$i` и `$j` лучше не использовать.
|
||
|
|
||
|
Пример:
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
class Foo
|
||
|
{
|
||
|
public $publicProp1;
|
||
|
public $publicProp2;
|
||
|
|
||
|
protected $protectedProp;
|
||
|
|
||
|
private $_privateProp;
|
||
|
|
||
|
|
||
|
public function someMethod()
|
||
|
{
|
||
|
// ...
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 4.3. Методы
|
||
|
|
||
|
- При именовании методов и функций следует использовать `camelCase` с первой буквой в нижнем регистре;
|
||
|
- Имена должны быть понятными и отражать назначение функции;
|
||
|
- Методы классов должны быть объявлены с использованием одного из модификаторов `private`, `protected` или
|
||
|
`public`. Использование `var` недопустимо;
|
||
|
- Открывающая фигурная кавычка должна быть расположена на строке, следующей за строкой объявления функции.
|
||
|
|
||
|
```php
|
||
|
/**
|
||
|
* Документация
|
||
|
*/
|
||
|
class Foo
|
||
|
{
|
||
|
/**
|
||
|
* Документация
|
||
|
*/
|
||
|
public function bar()
|
||
|
{
|
||
|
// код
|
||
|
return $value;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 4.4 Блоки Документации
|
||
|
|
||
|
`@param`, `@var`, `@property` и `@return` должны описывать типы `boolean`, `integer`, `string`, `array` или `null`. Вы можете использовать и имена классов, например `Model` или `ActiveRecord`. Для типизированных массивов используйте `ClassName[]`.
|
||
|
|
||
|
### 4.5 Конструкторы
|
||
|
|
||
|
- Используйте `__construct` вместо старого стиля, применяемого в PHP 4.
|
||
|
|
||
|
## 5 PHP
|
||
|
|
||
|
### 5.1 Типы Данных
|
||
|
|
||
|
- Все типы данных и значения PHP должны быть в нижнем регистре. Это относится и к `true`, `false`, `null` и `array`.
|
||
|
|
||
|
Изменение типа существующей переменной считается плохой практикой. Постарайтесь не использовать такой подход, за исключением случаев, когда это действительно необходимо.
|
||
|
|
||
|
|
||
|
```php
|
||
|
public function save(Transaction $transaction, $argument2 = 100)
|
||
|
{
|
||
|
$transaction = new Connection; // плохо
|
||
|
$argument2 = 200; // хорошо
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 5.2 Строки
|
||
|
|
||
|
- Если строка не содержит переменных или одинарных кавычек, используйте одинарные кавычки;
|
||
|
|
||
|
```php
|
||
|
$str = 'Например так.';
|
||
|
```
|
||
|
|
||
|
- Если строка содержит одинарную кавычку, используйте двойные кавычки во избежание излишнего экранирования.
|
||
|
|
||
|
#### Подстановка переменных
|
||
|
|
||
|
```php
|
||
|
$str1 = "Привет, $username!";
|
||
|
$str2 = "Привет, {$username}!";
|
||
|
```
|
||
|
|
||
|
Следующий вариант запрещен:
|
||
|
|
||
|
```php
|
||
|
$str3 = "Привет, ${username}!";
|
||
|
```
|
||
|
|
||
|
#### Конкатенация
|
||
|
|
||
|
При конкатенации строк выделяйте точку пробелами:
|
||
|
|
||
|
```php
|
||
|
$name = 'Yii' . ' Framework';
|
||
|
```
|
||
|
|
||
|
Для длинных строк используйте следующий подход:
|
||
|
|
||
|
```php
|
||
|
$sql = "SELECT *"
|
||
|
. "FROM `post` "
|
||
|
. "WHERE `id` = 121 ";
|
||
|
```
|
||
|
|
||
|
### 5.3 Массивы
|
||
|
|
||
|
Для массивов мы используем краткий синтаксис, появившийся в PHP 5.4.
|
||
|
|
||
|
#### Индексированные массивы
|
||
|
|
||
|
- Не используйте отрицательные числа в качестве индексов массива.
|
||
|
|
||
|
Используйте следующий стиль:
|
||
|
|
||
|
```php
|
||
|
$arr = [3, 14, 15, 'Yii', 'Framework'];
|
||
|
```
|
||
|
|
||
|
При большом количестве элементов:
|
||
|
|
||
|
```php
|
||
|
$arr = [
|
||
|
3, 14, 15,
|
||
|
92, 6, $test,
|
||
|
'Yii', 'Framework',
|
||
|
];
|
||
|
```
|
||
|
|
||
|
#### Ассоциативные массивы
|
||
|
|
||
|
Для ассоциативных массивов используйте следующий стиль:
|
||
|
|
||
|
```php
|
||
|
$config = [
|
||
|
'name' => 'Yii',
|
||
|
'options' => ['usePHP' => true],
|
||
|
];
|
||
|
```
|
||
|
|
||
|
### 5.4 Управляющие конструкции
|
||
|
|
||
|
- Оставляйте один пробел перед открывающей круглой скобкой и после закрывающей круглой скобки в управляющих конструкциях;
|
||
|
- Операторы внутри круглых скобок должны разделяться пробелами;
|
||
|
- Открывающая фигурная скобка должна быть на той же строке;
|
||
|
- Закрывающая фигурная скобка должна быть на новой строке;
|
||
|
- Всегда используйте фигурные скобки для однострочных выражений.
|
||
|
|
||
|
```php
|
||
|
if ($event === null) {
|
||
|
return new Event();
|
||
|
}
|
||
|
if ($event instanceof CoolEvent) {
|
||
|
return $event->instance();
|
||
|
}
|
||
|
return null;
|
||
|
|
||
|
|
||
|
// такой код недопустим:
|
||
|
if (!$model && null === $event)
|
||
|
throw new Exception('test');
|
||
|
```
|
||
|
|
||
|
Старайтесь избегать использования `else` после `return` там, где это возможно.
|
||
|
Используйте [граничные операторы](https://refactoring.guru/ru/replace-nested-conditional-with-guard-clauses).
|
||
|
|
||
|
```php
|
||
|
$result = $this->getResult();
|
||
|
if (empty($result)) {
|
||
|
return true;
|
||
|
} else {
|
||
|
// дальнейшие вычисления
|
||
|
}
|
||
|
```
|
||
|
|
||
|
лучше переписать так:
|
||
|
|
||
|
```php
|
||
|
$result = $this->getResult();
|
||
|
if (empty($result)) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// дальнейшие вычисления
|
||
|
```
|
||
|
|
||
|
#### switch
|
||
|
|
||
|
Используйте следующий стиль для 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 Вызовы функций
|
||
|
|
||
|
```php
|
||
|
doIt(2, 3);
|
||
|
|
||
|
doIt(['a' => 'b']);
|
||
|
|
||
|
doIt('a', [
|
||
|
'a' => 'b',
|
||
|
'c' => 'd',
|
||
|
]);
|
||
|
```
|
||
|
|
||
|
### 5.6 Анонимные (lambda) функции
|
||
|
|
||
|
Не забывайте про пробелы между ключевыми словами `function`/`use` и открывающими круглыми скобками:
|
||
|
|
||
|
```php
|
||
|
// правильно
|
||
|
$n = 100;
|
||
|
$sum = array_reduce($numbers, function ($r, $x) use ($n) {
|
||
|
$this->doMagic();
|
||
|
$r += $x * $n;
|
||
|
return $r;
|
||
|
});
|
||
|
|
||
|
// неправильно
|
||
|
$n = 100;
|
||
|
$mul = array_reduce($numbers, function($r, $x) use($n) {
|
||
|
$this->doMagic();
|
||
|
$r *= $x * $n;
|
||
|
return $r;
|
||
|
});
|
||
|
```
|
||
|
|
||
|
Документация
|
||
|
-------------
|
||
|
|
||
|
- Для получения информации по синтаксису документации обратитесь к первоисточнику [PHPDoc](http://phpdoc.org/);
|
||
|
- Код без документации недопустим;
|
||
|
- Все файлы классов должны содержать блок документации в начале файла и блок документации непосредственно перед каждым классом;
|
||
|
- Нет необходимости использовать тег `@return` если метод не возвращает значение;
|
||
|
- Все виртуальные свойства классов, наследованных от `yii\base\Object`, документируются тегом `@property` в блоке документации класса;
|
||
|
Аннотации геттеров и сеттеров автоматически генерируются из соответствующих тегов `@return` or `@param`
|
||
|
посредством выполнения команды `./build php-doc` в соответствующем каталоге;
|
||
|
Вы можете добавить дополнительный тег `@property` для геттера или сеттера для пояснения назначения переменной метода, если это необходимо.
|
||
|
Например:
|
||
|
|
||
|
```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)
|
||
|
```
|
||
|
|
||
|
#### Файл
|
||
|
|
||
|
```php
|
||
|
<?php
|
||
|
/**
|
||
|
* @link http://www.yiiframework.com/
|
||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||
|
* @license http://www.yiiframework.com/license/
|
||
|
*/
|
||
|
```
|
||
|
|
||
|
#### Класс
|
||
|
|
||
|
```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\Object
|
||
|
```
|
||
|
|
||
|
|
||
|
#### Функция / метод
|
||
|
|
||
|
```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];
|
||
|
}
|
||
|
```
|
||
|
|
||
|
#### Разметка
|
||
|
|
||
|
Как вы можете видеть в примерах выше, мы используем специальную разметку для форматирования комментариев PHPDoc.
|
||
|
|
||
|
Ниже описан дополнительный синтаксис для описания связей между классами, методами и свойствами в документации:
|
||
|
|
||
|
- `'[[canSetProperty]] ` создаст ссылку на метод или свойство `canSetProperty` этого класса;
|
||
|
- `'[[Component::canSetProperty]]` создаст ссылку на метод `canSetProperty` класса `Component` того же пространства имен;
|
||
|
- `'[[yii\base\Component::canSetProperty]]` создаст ссылку на метод `canSetProperty` класса `Component` в пространстве имен `yii\base`;
|
||
|
- `'[[Component]]` создаст ссылку на класс `Component` в том же пространстве имен. Здесь так же возможно явное указание пространства имен.
|
||
|
|
||
|
Для явного указания текста ссылки возможно использование следующего синтаксиса:
|
||
|
|
||
|
```
|
||
|
... as displayed in the [[header|header cell]].
|
||
|
```
|
||
|
|
||
|
Часть до | это имя свойства, метода или класса для ссылки, а часто поле | это текст ссылки.
|
||
|
|
||
|
Так же, возможно создание ссылок на Руководство:
|
||
|
|
||
|
```markdown
|
||
|
[Руководство](guide:file-name.md)
|
||
|
[Раздел руководства](guide:file-name.md#subsection)
|
||
|
```
|
||
|
|
||
|
|
||
|
#### Комментарии
|
||
|
|
||
|
- Однострочные комментарии должны начинаться с `//`, а не с `#`;
|
||
|
- Однострочные комментарии должны располагаться на отдельной строке.
|
||
|
|
||
|
Дополнительные правила
|
||
|
----------------
|
||
|
|
||
|
### `=== []` или `empty()`
|
||
|
|
||
|
Используйте `empty()`, где это возможно.
|
||
|
|
||
|
### Несколько точек возврата
|
||
|
|
||
|
Не допускайте запутанных вложенных условных конструкций, используйте return. Для коротких методов это не актуально.
|
||
|
|
||
|
### `self` или `static`
|
||
|
|
||
|
Всегда используйте `static`, за исключением следующих случаев:
|
||
|
|
||
|
- доступ к константам ДОЛЖЕН осуществляться через `self`: `self::MY_CONSTANT`;
|
||
|
- доступ к защищенным статическим свойствам ДОЛЖЕН осуществляться через `self`: `self::$_events`;
|
||
|
- допустимо использовать `self` для рекурсивного обращения к текущему классу, вместо класса наследника.
|
||
|
|
||
|
### Значение "ничего не делать"
|
||
|
|
||
|
Свойства указывающее компоненту на отсутствие необходимости что-либо делать, должны принимать значение `false`. `null`, `''`, or `[]` не должны использоваться в таких случаях.
|
||
|
|
||
|
### Каталоги/пространства имен
|
||
|
|
||
|
- Используйте нижний регистр;
|
||
|
- используйте множественную форму для существительных, представляющих объекты (например валидаторы);
|
||
|
- используйте единичную форму для имен, представляющих соответствующий функционал (например web).
|