Оформлення основного коду фреймворку Yii 2 ========================================== Нижченаведений стиль кодування використовується у розробці основного коду 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`. ### 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 '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`, де це має сенс. Використовуйте [вартові умови](http://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html). ```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 Оголошення анонімних (лямбда) функцій Зверніть увагу на пробіл між `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/) для довідки про синтаксис документації. - Код без документації не допускається. - Усі файли класів повинні містити файловий ("file-level") doc-блок на початку та класовий ("class-level") doc-блок безпосередньо над кожним класом. - Нема потреби використовувати `@return`, якщо метод нічого не повертає. - Усі віртуальні властивості у класах успадкованих від `yii\base\Object` документуються з тегом `@property` у класовому doc-блоці. Ці анотації генеруються автоматично із тегів `@return` чи `@param` відповідних геттерів або сеттерів виконанням команди `./build php-doc` у директорії build. Ви можете додати тег `@property` до геттеру або сеттеру, щоб точно визначити повідомлення для документації властивості, яка представляється цими методами, коли опис відрізняється від того, що встановлено тегом `@return`. Наприклад: ```php * @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]; } ``` #### 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)