21 KiB
Стиль кодирования Yii 2 framework
Описанный ниже стиль кодирования используется при разработке ядра Yii 2.x и его официальных расширений. Если вы хотите участвовать в разработке фреймворка, постарайтесь придерживаться данного стиля. Мы не принуждаем вас использовать этот стиль при разработке ваших приложений с использованием Yii 2. В данном случае можете использовать тот стиль, который вам больше подходит.
Пример конфигурационного файла для CodeSniffer вы можете найти здесь: https://github.com/yiisoft/yii2-coding-standards
1. Обзор
В общем, мы используем совместимый со стандартом PSR-2 стиль, так что все положения PSR-2 вполне применимы к нашему стилю кодирования.
- ДОЛЖНЫ использоваться только открывающие теги
<?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 файле должен быть только один класс;
- Все классы должны использовать пространства имен;
- Имя класса должно совпадать с именем файла. Пространство имен класса должно соответствовать структуре каталогов.
/**
* Документация
*/
class MyClass extends \yii\base\BaseObject implements MyInterface
{
// код
}
4.1. Константы
Константы класса ДОЛЖНЫ быть объявлены в верхнем регистре с подчеркиванием в качестве разделителей. Пример:
<?php
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
}
4.2. Свойства
- При объявлении общедоступных (public) членов класса нужно использовать ключевое слово
public
; - Общедоступные и защищенные (protected) переменные должны быть объявлены в начале класса, раньше объявления методов; Закрытые (private) переменные, так же, должны быть объявлены в начале класса, но могут быть добавлены и непосредственно перед методами, использующими их, в случае, если эти переменные используются только небольшой частью методов класса;
- Порядок объявления свойств класса должен соответствовать их видимости: общедоступные, защищенные и закрытые;
- Ограничений на порядок свойств одной области видимости нет;
- Для улучшения читаемости, следует не оставлять пустых строк между объявлением свойств и оставлять две пустые строки между объявлениями переменных и методов. Между объявлениями свойств разной области видимости должна быть добавлена одна пустая строка;
- Закрытые переменные должны иметь имя вида
$_varName
; - Общедоступные члены класса и отдельные переменные должны использовать
$camelCase
с первой буквой в нижнем регистре; - Используйте понятные имена. Переменные вроде
$i
и$j
лучше не использовать.
Пример:
<?php
class Foo
{
public $publicProp1;
public $publicProp2;
protected $protectedProp;
private $_privateProp;
public function someMethod()
{
// ...
}
}
4.3. Методы
- При именовании методов и функций следует использовать
camelCase
с первой буквой в нижнем регистре; - Имена должны быть понятными и отражать назначение функции;
- Методы классов должны быть объявлены с использованием одного из модификаторов
private
,protected
илиpublic
. Использованиеvar
недопустимо; - Открывающая фигурная кавычка должна быть расположена на строке, следующей за строкой объявления функции.
/**
* Документация
*/
class Foo
{
/**
* Документация
*/
public function bar()
{
// код
return $value;
}
}
4.4 Блоки Документации
@param
, @var
, @property
и @return
должны описывать типы bool
, int
, string
, array
или null
. Вы можете использовать и имена классов, например Model
или ActiveRecord
. Для типизированных массивов используйте ClassName[]
.
4.5 Конструкторы
- Используйте
__construct
вместо старого стиля, применяемого в PHP 4.
5 PHP
5.1 Типы Данных
- Все типы данных и значения PHP должны быть в нижнем регистре. Это относится и к
true
,false
,null
иarray
.
Изменение типа существующей переменной считается плохой практикой. Постарайтесь не использовать такой подход, за исключением случаев, когда это действительно необходимо.
public function save(Transaction $transaction, $argument2 = 100)
{
$transaction = new Connection; // плохо
$argument2 = 200; // хорошо
}
5.2 Строки
- Если строка не содержит переменных или одинарных кавычек, используйте одинарные кавычки;
$str = 'Например так.';
- Если строка содержит одинарную кавычку, используйте двойные кавычки во избежание излишнего экранирования.
Подстановка переменных
$str1 = "Привет, $username!";
$str2 = "Привет, {$username}!";
Следующий вариант запрещен:
$str3 = "Привет, ${username}!";
Конкатенация
При конкатенации строк выделяйте точку пробелами:
$name = 'Yii' . ' Framework';
Для длинных строк используйте следующий подход:
$sql = "SELECT *"
. "FROM `post` "
. "WHERE `id` = 121 ";
5.3 Массивы
Для массивов мы используем краткий синтаксис, появившийся в PHP 5.4.
Индексированные массивы
- Не используйте отрицательные числа в качестве индексов массива.
Используйте следующий стиль:
$arr = [3, 14, 15, 'Yii', 'Framework'];
При большом количестве элементов:
$arr = [
3, 14, 15,
92, 6, $test,
'Yii', 'Framework',
];
Ассоциативные массивы
Для ассоциативных массивов используйте следующий стиль:
$config = [
'name' => 'Yii',
'options' => ['usePHP' => true],
];
5.4 Управляющие конструкции
- Оставляйте один пробел перед открывающей круглой скобкой и после закрывающей круглой скобки в управляющих конструкциях;
- Операторы внутри круглых скобок должны разделяться пробелами;
- Открывающая фигурная скобка должна быть на той же строке;
- Закрывающая фигурная скобка должна быть на новой строке;
- Всегда используйте фигурные скобки для однострочных выражений.
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
там, где это возможно.
Используйте граничные операторы.
$result = $this->getResult();
if (empty($result)) {
return true;
} else {
// дальнейшие вычисления
}
лучше переписать так:
$result = $this->getResult();
if (empty($result)) {
return true;
}
// дальнейшие вычисления
switch
Используйте следующий стиль для switch:
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 Вызовы функций
doIt(2, 3);
doIt(['a' => 'b']);
doIt('a', [
'a' => 'b',
'c' => 'd',
]);
5.6 Анонимные (lambda) функции
Не забывайте про пробелы между ключевыми словами function
/use
и открывающими круглыми скобками:
// правильно
$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;
- Код без документации недопустим;
- Все файлы классов должны содержать блок документации в начале файла и блок документации непосредственно перед каждым классом;
- Нет необходимости использовать тег
@return
если метод не возвращает значение; - Все виртуальные свойства классов, наследованных от
yii\base\BaseObject
, документируются тегом@property
в блоке документации класса; Аннотации геттеров и сеттеров автоматически генерируются из соответствующих тегов@return
or@param
посредством выполнения команды./build php-doc
в соответствующем каталоге; Вы можете добавить дополнительный тег@property
для геттера или сеттера для пояснения назначения переменной метода, если это необходимо. Например:
<?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
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
Класс
/**
* 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
Функция / метод
/**
* 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]].
Часть до | это имя свойства, метода или класса для ссылки, а часто поле | это текст ссылки.
Так же, возможно создание ссылок на Руководство:
[Руководство](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
, ''
, или []
не должны использоваться в таких случаях.
Каталоги/пространства имен
- Используйте нижний регистр;
- используйте множественное число для существительных, представляющих объекты (например валидаторы);
- используйте единственное число для имен, представляющих соответствующий функционал (например web);
- предпочтительнее использовать однословные пространства имён;
- если одно слово использовать не удаётся, используйте camelCase стиль.