Nette Documentation Preview

syntax
Стандарт кодирования
********************

.[perex]
Этот документ описывает правила и рекомендации для разработки Nette. Внося код в Nette, вы обязаны им следовать. Проще всего добиться этого, подражая существующему коду. Цель в том, чтобы весь код выглядел так, будто его написал один человек.

Стандарт кодирования Nette соответствует [PSR-12 Extended Coding Style |https://www.php-fig.org/psr/psr-12/] с двумя главными исключениями: для отступов он использует [табуляции вместо пробелов |#Табуляции вместо пробелов] и [PascalCase для констант классов|https://blog.nette.org/en/for-less-screaming-in-the-code].

.[tip]
Многие из этих правил умеет автоматически проверять и исправлять инструмент [Nette Coding Standard |tools:coding-standard], так что проверять их вручную вам не придётся.


Общие правила
=============

- Каждый PHP-файл должен содержать `declare(strict_types=1)`
- Для разделения методов ради лучшей читаемости используются две пустые строки
- Причина использования оператора подавления (`@`) должна быть задокументирована: `@mkdir($dir); // @ - directory may exist`
- Если используется оператор нестрогого сравнения (то есть `==`, `!=`, ...), намерение должно быть задокументировано: `// == to accept null`
- Несколько классов исключений можно записать в один файл с именем `exceptions.php`, а несколько перечислений - в `enums.php`
- У интерфейсов видимость методов не указывается, потому что они всегда публичные
- У каждого свойства, возвращаемого значения и параметра должен быть указан тип. И наоборот, у финальных констант тип мы никогда не указываем, потому что он очевиден
- Для ограничения строк следует использовать одинарные кавычки, кроме случаев, когда сам литерал содержит апострофы


Соглашения об именовании
========================

- Избегайте сокращений, если только полное имя не окажется чрезмерным
- Для двухбуквенных сокращений используйте прописные буквы, а для более длинных - PascalCase/camelCase
- Для имени класса используйте существительное или именное словосочетание
- Имена классов должны содержать не только конкретику (`Array`), но и общность (`ArrayIterator`). Исключение - атрибуты PHP
- "Константы классов и перечисления следует писать в PascalCaps":https://blog.nette.org/en/for-less-screaming-in-the-code
- "Интерфейсы и абстрактные классы не должны содержать приставок или суффиксов":https://blog.nette.org/en/prefixes-and-suffixes-do-not-belong-in-interface-names вроде `Abstract`, `Interface` или `I`


Переносы и скобки
=================

Стандарт кодирования Nette соответствует PSR-12 (или PER Coding Style), но в некоторых пунктах уточняет или меняет его:

- Стрелочные функции пишутся без пробела перед скобкой, то есть `fn($a) => $b`
- Пустая строка между разными видами импортов `use` не требуется
- Возвращаемый тип функции или метода и открывающая фигурная скобка всегда находятся на разных строках:

```php
	public function find(
		string $dir,
		array $options,
	): array
	{
		// тело метода
	}
```

Открывающая фигурная скобка на отдельной строке важна для визуального отделения сигнатуры функции или метода от тела. Если сигнатура на одной строке, разделение очевидно (изображение слева). Если она на нескольких строках, в PSR сигнатура и тело сливаются (посередине), а в стандарте Nette остаются разделёнными (справа):

[* new-line-after.webp *]


Блоки документации (phpDoc)
===========================

Главное правило: **никогда не дублируйте** сведения из сигнатуры, такие как тип параметра или возвращаемый тип, если это не добавляет ценности.

Блок документации к определению класса:

- Начинается с описания класса
- Дальше пустая строка
- Дальше аннотации `@property` (или `@property-read`, `@property-write`), по одной на строку. Синтаксис: аннотация, пробел, тип, пробел, `$имя`
- Дальше аннотации `@method`, по одной на строку. Синтаксис: аннотация, пробел, возвращаемый тип, пробел, `имя(тип $параметр, ...)`
- Аннотация `@author` опускается. Авторство хранится в истории исходного кода
- Можно использовать аннотации `@internal` или `@deprecated`

```php
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */
```

Блок документации к свойству, содержащий только аннотацию `@var`, должен быть на одной строке:

```php
/** @var string[] */
private array $name;
```

Блок документации к определению метода:

- Начинается с краткого описания метода
- Без пустой строки
- Аннотации `@param`, по одной на строку
- Аннотация `@return`
- Аннотации `@throws`, по одной на строку
- Можно использовать аннотации `@internal` или `@deprecated`

За каждой аннотацией следует один пробел, кроме `@param`, за которой ради лучшей читаемости следуют два пробела.

```php
/**
 * Finds a file in directory.
 * @param  string[]  $options
 * @return string[]
 * @throws DirectoryNotFoundException
 */
public function find(string $dir, array $options): array
```


Глобальные функции и константы
==============================

Глобальные функции и константы пишутся без ведущего обратного слеша, то есть `count($arr)`, а не `\count($arr)`. Для функций, которые PHP умеет оптимизировать, добавьте в начало файла `use function`, чтобы компилятор мог перевести их эффективнее. К ним относятся функции вроде `count`, `strlen`, `is_array`, `is_string`, `is_scalar`, `sprintf` и т. п. Функции перечисляются на одной строке, чтобы блок импортов оставался компактным:

```php
use Nette;
use function count, is_array, is_scalar, sprintf;
```

Изредка мы импортируем и константы, знание значения которых может помочь компилятору:

```php
use const PHP_OS_FAMILY;
```


Табуляции вместо пробелов
=========================

У табуляций есть несколько преимуществ перед пробелами:

- Размер отступа настраивается в редакторах и в "вебе":https://developer.mozilla.org/en-US/docs/Web/CSS/tab-size
- Они не навязывают коду предпочтения автора по размеру отступа, благодаря чему код становится переносимее
- Их можно ввести одним нажатием клавиши (где угодно, а не только в редакторах, которые преобразуют табуляции в пробелы)
- Отступ - их прямое назначение
- Они учитывают нужды слабовидящих и слепых коллег

Используя в наших проектах табуляции, мы даём возможность настроить ширину, что большинству людей может показаться ненужным, но для людей с нарушениями зрения это принципиально важно.

Для слепых программистов, использующих брайлевские дисплеи, каждый пробел означает одну брайлевскую ячейку. Так что если отступ по умолчанию равен 4 пробелам, отступ 3-го уровня тратит 12 ценных брайлевских ячеек ещё до начала кода. На дисплее из 40 ячеек, самом распространённом для ноутбуков, это больше четверти доступных ячеек, потраченных впустую и не несущих никаких сведений.


{{priority: -1}}

Стандарт кодирования

Этот документ описывает правила и рекомендации для разработки Nette. Внося код в Nette, вы обязаны им следовать. Проще всего добиться этого, подражая существующему коду. Цель в том, чтобы весь код выглядел так, будто его написал один человек.

Стандарт кодирования Nette соответствует PSR-12 Extended Coding Style с двумя главными исключениями: для отступов он использует табуляции вместо пробелов и PascalCase для констант классов.

Многие из этих правил умеет автоматически проверять и исправлять инструмент Nette Coding Standard, так что проверять их вручную вам не придётся.

Общие правила

  • Каждый PHP-файл должен содержать declare(strict_types=1)
  • Для разделения методов ради лучшей читаемости используются две пустые строки
  • Причина использования оператора подавления (@) должна быть задокументирована: @mkdir($dir); // @ - directory may exist
  • Если используется оператор нестрогого сравнения (то есть ==, !=, …), намерение должно быть задокументировано: // == to accept null
  • Несколько классов исключений можно записать в один файл с именем exceptions.php, а несколько перечислений – в enums.php
  • У интерфейсов видимость методов не указывается, потому что они всегда публичные
  • У каждого свойства, возвращаемого значения и параметра должен быть указан тип. И наоборот, у финальных констант тип мы никогда не указываем, потому что он очевиден
  • Для ограничения строк следует использовать одинарные кавычки, кроме случаев, когда сам литерал содержит апострофы

Соглашения об именовании

Переносы и скобки

Стандарт кодирования Nette соответствует PSR-12 (или PER Coding Style), но в некоторых пунктах уточняет или меняет его:

  • Стрелочные функции пишутся без пробела перед скобкой, то есть fn($a) => $b
  • Пустая строка между разными видами импортов use не требуется
  • Возвращаемый тип функции или метода и открывающая фигурная скобка всегда находятся на разных строках:
	public function find(
		string $dir,
		array $options,
	): array
	{
		// тело метода
	}

Открывающая фигурная скобка на отдельной строке важна для визуального отделения сигнатуры функции или метода от тела. Если сигнатура на одной строке, разделение очевидно (изображение слева). Если она на нескольких строках, в PSR сигнатура и тело сливаются (посередине), а в стандарте Nette остаются разделёнными (справа):

Блоки документации (phpDoc)

Главное правило: никогда не дублируйте сведения из сигнатуры, такие как тип параметра или возвращаемый тип, если это не добавляет ценности.

Блок документации к определению класса:

  • Начинается с описания класса
  • Дальше пустая строка
  • Дальше аннотации @property (или @property-read, @property-write), по одной на строку. Синтаксис: аннотация, пробел, тип, пробел, $имя
  • Дальше аннотации @method, по одной на строку. Синтаксис: аннотация, пробел, возвращаемый тип, пробел, имя(тип $параметр, ...)
  • Аннотация @author опускается. Авторство хранится в истории исходного кода
  • Можно использовать аннотации @internal или @deprecated
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */

Блок документации к свойству, содержащий только аннотацию @var, должен быть на одной строке:

/** @var string[] */
private array $name;

Блок документации к определению метода:

  • Начинается с краткого описания метода
  • Без пустой строки
  • Аннотации @param, по одной на строку
  • Аннотация @return
  • Аннотации @throws, по одной на строку
  • Можно использовать аннотации @internal или @deprecated

За каждой аннотацией следует один пробел, кроме @param, за которой ради лучшей читаемости следуют два пробела.

/**
 * Finds a file in directory.
 * @param  string[]  $options
 * @return string[]
 * @throws DirectoryNotFoundException
 */
public function find(string $dir, array $options): array

Глобальные функции и константы

Глобальные функции и константы пишутся без ведущего обратного слеша, то есть count($arr), а не \count($arr). Для функций, которые PHP умеет оптимизировать, добавьте в начало файла use function, чтобы компилятор мог перевести их эффективнее. К ним относятся функции вроде count, strlen, is_array, is_string, is_scalar, sprintf и т. п. Функции перечисляются на одной строке, чтобы блок импортов оставался компактным:

use Nette;
use function count, is_array, is_scalar, sprintf;

Изредка мы импортируем и константы, знание значения которых может помочь компилятору:

use const PHP_OS_FAMILY;

Табуляции вместо пробелов

У табуляций есть несколько преимуществ перед пробелами:

  • Размер отступа настраивается в редакторах и в вебе
  • Они не навязывают коду предпочтения автора по размеру отступа, благодаря чему код становится переносимее
  • Их можно ввести одним нажатием клавиши (где угодно, а не только в редакторах, которые преобразуют табуляции в пробелы)
  • Отступ – их прямое назначение
  • Они учитывают нужды слабовидящих и слепых коллег

Используя в наших проектах табуляции, мы даём возможность настроить ширину, что большинству людей может показаться ненужным, но для людей с нарушениями зрения это принципиально важно.

Для слепых программистов, использующих брайлевские дисплеи, каждый пробел означает одну брайлевскую ячейку. Так что если отступ по умолчанию равен 4 пробелам, отступ 3-го уровня тратит 12 ценных брайлевских ячеек ещё до начала кода. На дисплее из 40 ячеек, самом распространённом для ноутбуков, это больше четверти доступных ячеек, потраченных впустую и не несущих никаких сведений.