Нижченаведений стиль кодування використовується у розробці основного коду Yii 2.x та офіційних розширень. Дотримуйтесь його,
якщо хочете вносити зміни в основний код. Команда розробників не наполягає на використанні цього стилю для вашого додатка.
Вільно обирайте те, що підходить вам більше.
Ви можете отримати конфігурацію для 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`.
- Імена приватних властивостей ПОВИННІ починатись з підкреслення.
- Завжди використовуйте `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.
- Код всередині класу повинен бути зміщений на рівень відступу.
- Один 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`.
- Публічні та захищені змінні повинні бути оголошенні у початку класу перед будь-яким оголошенням методу.
Приватні змінні також повинні бути оголошенні у початку класу, але можуть бути вставленні безпосередньо перед методами,
що ними оперують, у випадках коли змінні пов’язані лише з невеликою кількістю методів класу.
- Порядок оголошення властивостей у класі повинен бути таким: спочатку публічні, потім захищені, а потім приватні.
- Для кращої читабельності не повинно бути пустих рядків між оголошеннями властивостей та повинно бути два пустих рядки
між секціями оголошення властивості та методу.
- Приватні змінні повинні іменуватись як `$_varName`.
- Публічні члени класу та автономні змінні повинні іменуватись як `$camelCase`
(перша літера у нижньому регістрі).
- Використовуйте описові імена. Змінні, такі як `$i` та `$j`, краще не використовувати.
Наприклад:
```php
<?php
class Foo
{
public $publicProp;
protected $protectedProp;
private $_privateProp;
}
```
### 4.3. Методи
- Функції та методи повинні іменуватись як `camelCase` (перша літера у нижньому регістрі).
- Ім’я повинне бути само-описовим та вказувати призначення функції.
- Методи класу завжди повинні оголошувати видимість, використовуючи модифікатори `private`, `protected` та
`public`. Не допускається використання `var`.
- Початкова фігурна дужка функції повинна розміщуватись на наступному рядку після оголошення функції.
```
/**
* Документація
*/
class Foo
{
/**
* Документація
*/
public function bar()
{
// код
return $value;
}
}
```
### 4.4 Блоки документації PHPDoc (Doc-блоки)
`@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';
```
Для довгих текстових рядків використовуйте наступний формат:
```php
$sql = "SELECT *"
. "FROM `post` "
. "WHERE `id` = 121 ";
```
### 5.3 Масиви
Для масивів використовуйте скорочений синтаксис (PHP 5.4).
#### Індексовані масиви
- Не використовуйте від’ємні числа для індексів масиву.
*@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
Як ви могли побачити у прикладах вище, для форматування коментарів PHPDoc використовується markdown.
Існує додатковий синтаксис для створення перехресних посилань між класами, методами та властивостями у документації:
-`'[[canSetProperty]] ` створить посилання на метод або властивість `canSetProperty` того ж самого класу.
-`'[[Component::canSetProperty]]` створить посилання на метод `canSetProperty` класу `Component` в тому ж самому просторі імен.
-`'[[yii\base\Component::canSetProperty]]` створить посилання на метод `canSetProperty` класу `Component` з простору імен `yii\base`.
-`'[[Component]]` створить посилання на клас `Component` в тому ж самому просторі імен. Додавання простору імен до імені класу тут також можливе.
Щоб для одного з вище зазначених посилань вказати мітку відмінну від імені класу чи методу, ви можете використовувати синтаксис, показаний в нижченаведеному прикладі:
```
... as displayed in the [[header|header cell]].
```
Частина перед | є найменуванням методу, властивості або класу, в той час як частина після | є міткою посилання.
Також можливо посилатись на Посібник, використовуючи наступний синтаксис:
```markdown
[link to guide](guide:file-name.md)
[link to guide](guide:file-name.md#subsection)
```
#### Коментарі
- Одно-рядкові коментарі повинні починатись з `//`, а не з `#`.
- Одно-рядковий коментар повинен бути розміщений на власному рядку.
Додаткові правила
-----------------
### `=== []` проти `empty()`
Використовуйте `empty()`, де можливо.
### Кілька інструкцій return
При великій вкладеності умов, використовуйте інструкцію return раніше. Якщо метод не великий, це неважливо.
### `self` проти `static`
Завжди використовуйте `static`, за виключенням наведених випадків:
- отримання значень констант ПОВИННО виконуватись через `self`: `self::MY_CONSTANT`
- отримання значень приватних статичних властивостей ПОВИННО виконуватись через `self`: `self::$_events`
- Дозволено використовувати `self` для рекурсії, щоб викликати поточне втілення знову замість розширення реалізації класу.
### Значення для "не робити чогось"
Властивості, яким дозволено сконфігурувати компонент не робити чогось, повинні приймати значення `false`. Значення `null`, `''` чи `[]` не повинні вважатись такими.
### Імена директорій та просторів імен
- використовуйте нижній регістр
- використовуйте форму множини для іменників, які представляють об’єкти (наприклад, validators)
- використовуйте форму однини для імен, які представляють відповідну функціональність/можливості (наприклад, web)