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

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

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

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

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

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

  • Избегайте использования сокращений, если только полное имя не является чрезмерным.
  • Используйте верхний регистр для двухбуквенных аббревиатур и верблюжий (CamelCase) регистр для более длинных аббревиатур.
  • Используйте существительное или словосочетание для названия класса.
  • Имена классов должны содержать не только специфичность (Array), но и общность (ArrayIterator). Исключением являются атрибуты PHP.
  • Интерфейсы и абстрактные классы не должны содержать префиксы или постфиксы типа Abstract, Interface или I.

Обертывание и брекеты

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

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

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

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

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

  • Начинается с описания класса.
  • Далее следует пустая строка.
  • Далее следуют аннотации @property (или @property-read, @property-write), одна за другой. Синтаксис следующий: аннотация, пробел, тип, пробел, $name.
  • Далее следуют аннотации @method, одна за другой. Синтаксис следующий: аннотация, пробел, возвращаемый тип, пробел, имя(тип $param, …).
  • Аннотация @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

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

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

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

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

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