Мета-документ расширенного руководства по стилю кодирования
1. Краткое описание
Этот документ описывает процесс и обсуждения, которые привели к созданию PSR расширенного стиля кодирования. Его цель — объяснить причины, лежащие в основе каждого решения.
2. Зачем это нужно?
PSR-2 был принят в 2012 году, и с тех пор в PHP был внесён ряд изменений, в первую очередь недавние изменения для PHP 7, которые влекут за собой последствия для руководящих принципов стиля кодирования. Хотя PSR-2 весьма исчерпывающе охватывает функциональность PHP, существовавшую на момент написания, новая функциональность очень открыта для интерпретации. PSR-12 призван предоставить единый подход, который могут реализовать инструменты стиля кодирования, проекты могут декларировать соответствие ему, а разработчики могут легко ориентироваться между различными проектами, снижая когнитивную нагрузку.
PSR-2 был создан на основе общих практик проектов PHP-FIG того времени, но в итоге это означало компромисс из руководящих принципов многих различных проектов. Последствия изменения проектами своих руководящих принципов для приведения их в соответствие с PSR-2 (почти все проекты соответствуют PSR-1, даже если это явно не заявлено) были признаны слишком значительными (потеря истории git, огромные наборы изменений и нарушение существующих патчей/запросов на слияние).
PSR-2 требовал от последователей переформатирования больших объёмов существующего кода, что сдерживало его принятие. Чтобы помочь решить эту проблему в PSR-12, мы применили более директивный подход и определили стандарты для новых языковых возможностей по мере их появления.
Тем не менее, не желая быть диктаторскими, мы будем стремиться применять стилистику, обоснование и позиции PSR-2 (описанные в Разделе 4, Подходы) в PSR-12 вместо введения новых соглашений.
3. Область применения
3.1. Цели
Данный PSR разделяет те же цели, что и PSR-2.
Цель данного руководства — снизить когнитивную нагрузку при изучении кода от разных авторов. Это достигается путём перечисления общего набора правил и ожиданий относительно форматирования PHP-кода. Когда различные авторы сотрудничают в рамках нескольких проектов, полезно иметь единый набор руководящих принципов, применяемых во всех этих проектах. Таким образом, преимущество данного руководства заключается не в самих правилах, а в их совместном использовании.
Данный PSR является расширением PSR-2 и, следовательно, также расширением PSR-1. Основой PSR-12 является PSR-2, поэтому ниже приведён список различий для помощи при миграции, однако его следует рассматривать как самостоятельную спецификацию.
Данный PSR будет включать руководящие принципы стиля кодирования, связанные с новой функциональностью, добавленной в PHP после публикации PSR-2; это включает PHP 5.5, PHP 5.6 и PHP 7.0. Данный PSR также будет включать разъяснения текста PSR-2, описанные в Errata PSR-2.
3.2. Не входит в область применения
Данный PSR не предназначен для введения полностью новых руководящих принципов стиля кодирования. PSR-12 также не изменяет ничего, предписанного в PSR-1 и PSR-2.
4. Подходы
Общий подход заключается в попытке применить существующую стилистику и обоснование PSR-2 к новой функциональности, а не вводить новые соглашения.
4.1. Объявление строгих типов
Состоялось обсуждение того, следует ли требовать строгие типы в стандарте: https://github.com/cs-extended/fig-standards/issues/7. Все согласились, что следует использовать только формулировки ОБЯЗАН или НЕ ДОЛЖЕН, избегая формулировки СЛЕДУЕТ, и никто не хотел запрещать объявление строгих типов. Обсуждалось, следует ли считать это элементом стиля кодирования, который должен быть охвачен, или это выходит за рамки, и было решено, что это выходит за рамки руководства по стилю кодирования.
4.2. Интервалы объявления finally и типов возвращаемых значений
Были предложены многочисленные различные варианты, которые можно увидеть здесь для объявлений типов возвращаемых значений или здесь для блоков finally, и текущая реализация была выбрана из-за согласованности с другими частями спецификации PSR-12, взятыми из PSR-2.
4.3. Принудительное использование краткой формы для всех ключевых слов типов
PHP 7.0 ввёл объявление скалярных типов, которое не поддерживает длинные псевдонимы типов. Поэтому имеет смысл принудительно использовать основные краткие формы типов для единообразного синтаксиса и предотвращения возможной путаницы.
4.4. Публичный опрос
В целях принятия решений на основе данных был проведён опрос, в котором были собраны ответы от 142 человек, включая 17 представителей проектов:
4.4.1. Результаты представителей PHP-FIG
| Представитель | Проект | Составные пространства имён с глубиной два и более НЕ ДОЛЖНЫ использоваться | Группировка и порядок заголовочных операторов | Операторы declare должны быть каждый на отдельной строке | Операторы declare в PHP-файлах с разметкой | Операторы declare без пробелов: declare(strict_types=1); |
Форматирование блочного оператора declare | Использование ключевого слова new, скобки обязательны |
Форматирование объявления типа возвращаемого значения | Ведущие слеши в операторах use запрещены | Форматирование блочного объявления пространства имён | Общие пробелы вокруг операторов | Форматирование try, catch, finally | Форматирование анонимного класса | Регистр ключевых слов, только нижний | Ключевые слова типов, только краткая форма |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Alexander Makarov | Yii framework | ✓ | ✓ | ✓ | ❌ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Korvin Szanto | concrete5 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Leo Feyer | Contao | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Larry Garfield | Drupal | ✓ | ✓ | ✓ | ✓ | ✓ | ❌ | ✓ | ✓ | ✓ | ❌ | ✓ | ✓ | ❌ | ✓ | ✓ |
| André R. | eZ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Jan Schneider | Horde | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Karsten Dambekalns | Neos and Flow | ✓ | ✓ | ✓ | ✓ | ❌ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Andres Gutierrez | Phalcon | ❌ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Ryan Thompson | PyroCMS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ❌ | ❌ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Matteo Beccati | Revive Adserver | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ❌ | ✓ | ✓ | ✓ | ✓ |
| Damian Mooyman | SilverStripe | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Brian Retterer | Stormpath PHP SDK | ✓ | ✓ | ✓ | ❌ | ❌ | ✓ | ❌ | ✓ | ❌ | ✓ | ✓ | ✓ | ✓ | ❌ | ❌ |
| Matthew Weier O'Phinney | Zend Framework | ❌ | ✓ | ✓ | ❌ | ✓ | ✓ | ✓ | ❌ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Jordi Boggiano | Composer | ❌ | ❌ | ❌ | ✓ | ✓ | ✓ | ❌ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Ben Marks | Magento | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Chuck Burgess | PEAR | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Итого: | 13/3 | 15/1 | 15/1 | 13/3 | 14/2 | 15/1 | 14/2 | 15/1 | 14/2 | 14/2 | 15/1 | 16/0 | 15/1 | 15/1 | 15/1 |
4.4.2. Общие голосующие (не представители)
| Вопрос | За | Против | Процент за |
|---|---|---|---|
| Требуемая глубина составных пространств имён | 114 | 12 | 89.47% |
| Группировка и порядок заголовочных операторов | 113 | 13 | 88.5% |
| Операторы declare должны быть каждый на отдельной строке | 120 | 6 | 95% |
| Операторы declare в PHP-файлах с разметкой | 119 | 7 | 94.12% |
| Операторы declare без пробелов | 116 | 10 | 91.38% |
| Форматирование блочного оператора declare | 118 | 8 | 93.22% |
Использование ключевого слова new, скобки обязательны |
116 | 10 | 91.38% |
| Форматирование объявления типа возвращаемого значения | 115 | 11 | 90.43% |
| Ведущие слеши в операторах use запрещены | 118 | 8 | 93.22% |
| Форматирование блочного объявления пространства имён | 120 | 6 | 95% |
| Общие пробелы вокруг операторов | 123 | 3 | 97.56% |
| Форматирование try, catch, finally | 124 | 2 | 98.39% |
| Форматирование анонимного класса | 117 | 9 | 92.31% |
| Регистр ключевых слов, только нижний | 124 | 2 | 98.39% |
| Ключевые слова типов, только краткая форма | 121 | 5 | 95.87% |
4.5. Многострочные аргументы функций в сочетании с многострочным возвращаемым значением
Потенциальная проблема читаемости была поднята в рассылке. Мы рассмотрели варианты изменений в спецификации, которые могли бы улучшить читаемость, и обсуждавшийся вариант заключался в требовании пустой строки после открывающей скобки функции, если и аргументы, и возвращаемое значение являются многострочными. Вместо этого было указано, что данная спецификация уже позволяет разработчикам самостоятельно решать, где добавлять пустые строки, поэтому мы оставим это на усмотрение реализаторов.
5. Журнал изменений относительно PSR-2
Обратите внимание, что этот журнал изменений не является подробным списком изменений относительно PSR-2, а лишь освещает наиболее заметные изменения. Его следует рассматривать как новую спецификацию, поэтому для полного понимания содержимого следует прочитать спецификацию.
5.1. Новые положения
- Нижний регистр для всех ключевых слов — Раздел 2.5
- Краткая форма для всех ключевых слов типов — Раздел 2.5
- Группировка операторов use — Раздел 3
- Блоки операторов use — Раздел 3
- Использование оператора declare / объявления строгих типов — Раздел 3
- Скобки всегда обязательны при создании экземпляров классов — Раздел 4
- Типизированные свойства — Раздел 4.3
- Объявления типов возвращаемых значений — Раздел 4.5
- Операторы вариативных и ссылочных аргументов — Раздел 4.5
- Подсказки типов — Раздел 4.5
- Добавление блока finally — Раздел 5.6
- Операторы — Раздел 6
- Унарные операторы — Раздел 6.1
- Бинарные операторы — Раздел 6.2
- Тернарные операторы — Раздел 6.3
- Анонимные классы — Раздел 8
5.2. Разъяснения и исправления
- Замена «methods» на «methods and functions» в ряде мест — По всему тексту
- Расширение ссылок на классы и интерфейсы с включением трейтов — По всему тексту
- Значение StudlyCaps уточнено как PascalCase — Раздел 2.1
- Последняя строка не должна быть пустой, а должна содержать символ конца строки — Раздел 2.2
- Пустые строки могут быть добавлены для улучшения читаемости, кроме случаев, явно запрещённых в PSR — Раздел 2.3
- Положение errata PSR-2 о многострочных аргументах — Раздел 4
- Положение errata PSR-2 о расширении нескольких интерфейсов — Раздел 4
- Запрет пустых строк перед/после закрывающих/открывающих скобок классов — Раздел 4
6. Участники
6.1. Редактор:
- Korvin Szanto
6.2. Спонсор:
- Chris Tankersley
6.3. Члены рабочей группы:
- Alessandro Lai
- Alexander Makarov
- Michael Cullum
- Robert Deutz
6.4. Отдельная благодарность
- Michael Cullum за составление исходной спецификации
- Alexandar Makarov за координацию черновика во время PHP-FIG 2.0
- Cees-Jan Kiewiet за моральную поддержку
7. Голосования
- Вступительное голосование: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/php-fig/P9atZLOcUBM/_jwkvlYKEAAJ
- Голосование об одобрении: https://groups.google.com/forum/#!topic/php-fig/1uaeSMaDGbk
8. Ссылки по теме
Примечание: Порядок убывающий хронологический.