стандарты написания кода php
PSR-2. Руководство по оформлению кода
Это руководство продолжает и расширяет PSR-1, основной стандарт написания кода.
Целью данного руководства является снижение когнитивных трений при беглом осмотре кода от разных авторов. Оно делает это путем перечисления общих наборов правил и ожиданий о том, как оформлять PHP код.
Эти правила оформления являются производным от сходства между разными участвующими проектами. Когда разные авторы сотрудничают в нескольких проектах, это помогает иметь один набор нормативов для использования между всеми этими проектами. Таким образом польза этого руководства не в самих правилах, а в обмене этими правилами.
Ключевые слова «ДОЛЖЕН», «НЕ ДОЛЖЕН», «ТРЕБУЕТСЯ», «БУДЕТ», «НЕ БУДЕТ», «СЛЕДУЕТ», «НЕ СЛЕДУЕТ», «РЕКОМЕНДУЕТСЯ», «МОЖЕТ», и «ДОПОЛНИТЕЛЬНО» в этом документе должны быть истолкованы как описано в RFC 2119.
1. Обзор
Код ДОЛЖЕН следовать PSR-1.
Код ДОЛЖЕН использовать 4 пробела для отступов, не табуляцию.
НЕ ДОЛЖНО быть жесткого ограничения на длину строки; мягкое ограничение ДОЛЖНО быть 120 знаков; строкам СЛЕДУЕТ быть 80 символов или менее.
Открывающие фигурные скобки для классов ДОЛЖНЫ быть на новой строке, и закрывающие фигурные скобки ДОЛЖНЫ быть на новой строке после тела класса.
Открывающие фигурные скобки для методов ДОЛЖНЫ быть на новой строке, и закрывающие фигурные скобки ДОЛЖНЫ быть на новой строке после тела метода.
Область видимости ДОЛЖНА быть описана у всех свойств и методов; abstract и final ДОЛЖНЫ быть описаны перед областью видимости; static ДОЛЖНО быть описано после области видимости.
Ключевые слова управляющих конструкций ДОЛЖНЫ иметь один пробел после себя; вызовы методов и функции НЕ ДОЛЖНЫ.
Открывающие фигурные скобки для управляющих конструкций ДОЛЖНЫ быть на той же строке, а закрывающие фигурные скобки ДОЛЖНЫ быть на новой строке после тела конструкции.
Открывающие круглые скобки для управляющих конструкций НЕ ДОЛЖНЫ иметь пробел после себя, а закрывающие круглые скобки для управляющих конструкций НЕ ДОЛЖНЫ иметь пробел перед собой.
1.1. Пример
Этот пример как краткий обзор включает в себя некоторые из ниже указанных правил:
2. Общее
2.1 Основной стандарт написания кода
Код ДОЛЖЕН следовать всем правилам изложенным в PSR-1.
2.2 Файлы
Все PHP файлы ДОЛЖНЫ использовать переводы строк Unix LF (linefeed).
Все PHP файлы ДОЛЖНЫ оканчиваться одной пустой строкой.
2.3. Строки
НЕ ДОЛЖНО быть жесткого ограничения на длину строки.
Мягкое ограничение на длину строки ДОЛЖНО быть 120 знаков; автоматические проверки стиля ДОЛЖНЫ предупредить но НЕ ДОЛЖНЫ выдавать ошибку на мягкие ограничения.
Строкам НЕ СЛЕДУЕТ быть длиннее 80 знаков; более длинные строки СЛЕДУЕТ разбивать на несколько последующих строк не более чем 80 знаков в каждой.
НЕ ДОЛЖНО быть замыкающий пробелов в конце строки на не пустых строках.
Пустые строки МОГУТ быть добавлены для улучшения читабельности и указания связанных блоков кода.
НЕ ДОЛЖНО быть более одного оператора в строке.
2.4. Отступы
Код ДОЛЖЕН использовать отступ в 4 пробела, и НЕ ДОЛЖЕН использовать табуляцию для отступов.
Обратите особое внимание: Использование только пробелов, и не смешивание пробелов и табуляции, помогает избежать проблем с диффами, патчами, историей, и аннотациями. Использование пробелов также позволяет легко вставить тонко-настроенный суб-отступ для межстрочного выравнивания.
2.5. Ключевые слова и True/False/Null
PHP Ключевые слова ДОЛЖНЫ быть в нижнем регистре.
3. Объявление Пространства имен и Use
ДОЛЖНО быть ключевое слово use на каждое объявление.
4. Классы, Свойства, и Методы
Термин «класс» относится ко всем классам, интерфейсам и трейтам.
4.1. Extends и Implements
Ключевые слова extends и implements ДОЛЖНЫ быть объявлены на той же строке, что и имя класса.
Открывающая фигурная скобка для класса ДОЛЖНА идти на своей собственной строке; закрывающая фигурная скобка для класса ДОЛЖНА идти на следующей строке после тела класса.
Список implements МОЖЕТ быть разделен на несколько строк, где каждая последующая строка с одним отступом. При этом первый элемент в списке ДОЛЖЕН быть на следующей строке, и ДОЛЖЕН быть только один интерфейс на строку.
4.2. Свойства
Область видимости ДОЛЖНА быть объявлена на все свойства.
Ключевое слово var НЕ ДОЛЖНО быть использовано для объявления свойства.
НЕ ДОЛЖНО быть более одного свойства объявленного на оператор.
Имена свойств НЕ СЛЕДУЕТ делать с подчеркиванием в качестве приставки для обозначения области видимости protected или private.
Объявление свойства выглядит следующим образом.
4.3. Методы
Область видимости ДОЛЖНА быть объявлена на все методы.
Имена методов НЕ СЛЕДУЕТ делать с подчеркиванием в качестве приставки для обозначения области видимости protected или private.
Имена методов НЕ ДОЛЖНЫ быть объявлены с пробелом после имени метода. Открывающая фигурная скобка ДОЛЖНА идти на своей собственной строке, а закрывающая фигурная скобка ДОЛЖНА быть на следующей строке после тела метода. НЕ ДОЛЖНО быть пробела после открытия круглой скобки, и НЕ ДОЛЖНО быть пробела перед закрывающей круглой скобкой.
Объявление метода выглядит следующим образом. Обратите внимание на размещение круглых скобок, запятых, пробелов и фигурных скобок:
4.4. Аргументы Метода
В списке аргументов, НЕ ДОЛЖНО быть пробела перед каждой запятой, и ДОЛЖЕН быть один пробел после каждой запятой.
Аргументы Метода со значениями по умолчанию должны идти в конце списка аргументов.
Список аргументов МОЖЕТ быть разделен на несколько строк, где каждая последующая строка с одним отступом. При этом первый элемент в списке ДОЛЖЕН быть на следующей строке, и ДОЛЖЕН быть только один аргумент на строку.
Когда список аргументов разделен на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ быть установлены вместе на их собственную строку с одним пробелом между ними.
Если они присутствуют, то abstract и final ДОЛЖНЫ предшествовать перед объявлением области видимости.
4.6. Вызовы Метода и Функции
При выполнении вызова метода или функции, НЕ ДОЛЖНО быть пробела между именем метода или функции и открывающей круглой скобкой, НЕ ДОЛЖНО быть пробела после открытия круглой скобки, а также НЕ ДОЛЖНО быть пробела перед закрывающей круглой скобкой. В списке аргументов, НЕ ДОЛЖНО быть пробела перед каждой запятой, и ДОЛЖЕН быть один пробел после каждой запятой.
Списки аргументов МОГУТ быть разделены на несколько строк, где каждая последующая строка с одним отступом. При этом первый элемент в списке ДОЛЖЕН быть на следующей строке, и ДОЛЖЕН быть только один аргумент на строку.
5. Управляющие конструкции
Общие правила стиля для управляющих конструкций следующие:
Тело каждой конструкции ДОЛЖНО быть заключено в фигурные скобки. Это стандартизирует вид конструкций, и уменьшает вероятность внесения ошибок при добавлении новых строк к телу управляющей конструкции.
Оператор if выглядит следующим образом. Обратите внимание на размещение круглых скобок, пробелов и фигурных скобок; и что else и elseif находятся на одной линии, как и закрывающая фигурная скобка тела оператора.
Ключевое слово elseif СЛЕДУЕТ использовать вместо else if так что все управляющие ключевые слова выглядят как единые слова.
Оператор while выглядит следующим образом. Обратите внимание на размещение круглых скобок, пробелов и фигурных скобок.
Кроме того, оператор do while выглядит следующим образом. Обратите внимание на размещение круглых скобок, пробелов и фигурных скобок.
5.4. for
Оператор for выглядит следующим образом. Обратите внимание на размещение круглых скобок, пробелов и фигурных скобок.
5.5. foreach
Оператор foreach выглядит следующим образом. Обратите внимание на размещение круглых скобок, пробелов и фигурных скобок.
Блок try catch выглядит следующим образом. Обратите внимание на размещение круглых скобок, пробелов и фигурных скобок.
6. Замыкания
Открывающая фигурная скобка ДОЛЖНА идти на той же строке, а закрывающая фигурная скобка ДОЛЖНА идти на следующей строке после тела функции.
НЕ ДОЛЖНО быть пробела после открывающей круглой скобки списка аргументов или списка переменных, и НЕ ДОЛЖНО быть пробела перед закрывающей круглой скобкой списка аргументов или списка переменных.
В списке аргументов и списке переменных НЕ ДОЛЖНО быть пробела перед каждой запятой, и ДОЛЖЕН быть один пробел после каждой запятой.
Аргументы замыкания со значениями по умолчанию должны идти в конце списка аргументов.
Объявление замыкания выглядит следующим образом. Обратите внимание на размещение круглых скобок, запятых, пробелов и фигурных скобок:
Список аргументов и список переменных МОЖЕТ быть разделен на несколько строк, где каждая последующая строка с одним отступом. При этом первый элемент в списке ДОЛЖЕН быть на следующей строке, и ДОЛЖЕН быть только один аргумент или переменная на строку.
Когда конечный список (или аргументов или переменных) разделен на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ быть установлены вместе на их собственную строку с одним пробелом между ними.
Ниже приведены примеры замыканий с и без списка аргументов и списка переменных разбитого на несколько строк.
Обратите внимание, что правила форматирования применяются также когда замыкание используется прямо как аргумент при вызове метода или функции.
7. Заключение
Есть много элементов оформления и практик умышленно опущенных в этом руководстве. Они включают, но не ограничиваются:
Объявление глобальных переменных и глобальных констант
Операторы и присваивания
Комментарии и блоки документации
Приставки и окончания имен классов
Будущее рекомендации МОГУТ пересмотреть и расширить это руководство для решения тех или иных элементов оформления и практик.
Стандарт PSR-12 на русском для PHP-разработчиков
Предисловие
PHP Standarts Recommendations — это рекомендации для PHP-разработчиков, разработанные PHP Framework Interop Group. Задача рекомендаций — помочь программистам унифицировать решения некоторых задач.
Redwerk.jobs первым сделал для вас перевод PSR-12. Соглашаться ли с рекомендациями — решать вам.
Общие положения
Ключевые слова «ДОЛЖНО», «НЕ ДОЛЖНО», «ТРЕБУЕТСЯ», «СЛЕДУЕТ», «НЕ СЛЕДУЕТ», «РЕКОМЕНДУЕТСЯ», «МОЖЕТ» и «НЕОБЯЗАТЕЛЬНЫЙ» в этом документе следует интерпретировать как описано в RFC 2119.
Эта спецификация расширяет и заменяет PSR-2, руководство по стилю кодирования, и требует соблюдения PSR-1, базового стандарта оформления кода.
Как и PSR-2, цель этой спецификации — упростить читаемость кода и убрать разногласия между разными авторами. Это достигается путем перечисления общего набора правил и ожиданий о том, как будет сформирован код PHP. Этот PSR предоставляет набор инструкций, которых могут придерживаться инструменты для форматирования, а разработчики могут легко установить связь между различными проектами. Когда различные авторы сотрудничают внутри одного проектами, это поможет иметь один набор руководящих принципов, который будет использоваться внутри проектов. Таким образом, преимущество этого руководства заключается не в самих правилах, а в совместном их использовании.
PSR-2 был принят в 2012 году, и с тех пор в PHP был внесен ряд изменений, которые повлияли на рекомендации по стилю кодирования. В то время как PSR-2 является довольно полным набором функционала PHP, который существовал на момент написания, новый функционал можно интерпретировать по-разному. Таким образом, этот PSR стремится прояснить содержание PSR-2 в более современном контексте, учитывая новые функциональные возможности.
Предыдущие версии языка
В этом документе любые инструкции МОГУТ быть проигнорированы, если они не существуют в версиях PHP, поддерживаемых вашим проектом.
Пример
Этот пример охватывает некоторые из приведенных ниже правил в качестве краткого обзора:
PHP Code Style Conventions
В данной статье рассматривается подход к написанию и оформлению PHP кода. Нижеизложенные моменты были сформированы путем анализа существующих подходов компаний и личного опыта.
Правила именования файлов и папок
Все названия для папок и файлов должны быть осмысленными и говорящими (не требующие дополнительного разъяснения).
Папки
Если папка хранит в себе классы, которые относятся к пространству имен (namespace), то папка именуется в соответствии с названием пространства имен (namespace).
Файлы
Если файл является файлом класса, то именуется в соответствии с названием класса.
Правила именования пространств имен, классов, методов и переменных
Все названия должны быть осмысленными и говорящими (не требующие дополнительного разъяснения).
Пространства имен
Названия пространств имен должны быть в нижнем регистре и состоять из одного слова. В случае необходимости именовать пространств имен более одного слова производится дробление на составные части, являющиеся вложенными пространствами имен.
Классы
Методы
К названиям методов применяются следующие правила:
Переменные
К названиям переменных применяются следующие правила:
Название переменной должно передавать намерения программиста
Название переменной должно сообщить, почему эта переменная существует, что она делает и как используется
Название переменной не должно быть коротким
Если переменная хранит признак, то он должен быть включен в название ( unpaidProject )
Переменные и свойства объекта должны являться существительными и называться так, чтобы они правильно читались при использовании, а не при инициализации
Плохо:
Хорошо:
Запрещены отрицательные логические названия
Плохо:
Хорошо:
Правила оформления кода
В первую очередь ставится пространство имен (namespace), которое используется (если есть). Далее пишется конструкции использования классов ( use ). В случае использования нескольких
классов одного пространства имен происходит группировка с помощью конструкции <. >. Далее идет объявление класса.
Фигурные скобки ставятся на той же строке и разделяются пробелом.
Каждая переменная должна быть объявлена на новой строке.
Условия и служебные вызовы методов разделяются переносом строки, переменные и работа с ними переносами строк не разделяются.
Внутри условий и циклов дополнительный перенос на новую строку не ставится.
Содержимое класса разделяется сверху одной пустой строкой.
Перед возвращаемым значением( return ) обязательно ставится перенос строки, если метод не состоит из единственной строки.
Если условие является большим, то обязательно выделить его в одно или несколько смысловых выражений и использовать его (их) в условии.
Плохо:
Хорошо:
Комментирование кода
В общем случае комментарии запрещены (НЕ «всегда»). Любой участок кода, который необходимо выделить или прокомментировать, надо выносить в отдельный метод.
Комментарии должны быть расположены перед объявлением классов, переменных и методов и быть оформлены в соответствии с PHPDoc. Комментарий перед классом должен содержать описание бизнес-логики и отражать его назначение с приведением примеров использования.
Готовые алгоритмы, взятые из внешнего источника, должны быть помечены ссылкой на источник.
Правила написания кода
Везде, где имеет смысл, должнно быть прописано declare(strict_types=1);
Нельзя изменять переменные, которые передаются в метод на вход (исключение — если эта переменная объект).
Строки обрамляются одинарными кавычками. Двойные кавычки используются только, если:
Вместо лишней конкатенации используем подстановку переменных в двойных кавычках
Метод должен явно отличать нормальные ситуации от исключительных.
По умолчанию тексты исключений не должны показываться пользователю. Они предназначены для логирования и отладки. Текст исключения можно показать пользователю, если оно явно для этого предназначено.
В условном операторе должно проверяться исключительно boolean значение. В сравнении не boolean переменных используется строгое сравнение с приведением типа ( === ), автоматическое приведение и нестрогое сравнение не используются.
При использовании в условном выражении одновременно операторов И и ИЛИ обязательно выделять приоритет скобками.
PSR Стандарты
PSR — Чуть больше, чем стиль оформления кода.
Как показала практика, многие PHP-разработчики знакомы с аббревиатурой PSR. Однако большинство все еще ограничены знанием, что PSR это стандарт оформления кода.
Ребята из PHP-FIG (PHP Framework Interop Group), группа концепций совместимости PHP, которые занимаются развитием PSR (PHP Standards Recommendations) шагнули далеко вперед. Поэтому давайте разберемся, что из себя представляет PSR…
За последние полгода мне пришлось провести множество собеседований на позицию Middle PHP-Developer.
Один из вопросов, который я задавал всем кандидатам, был:- «Знаете ли Вы, что такое PSR?»
Как оказалось, практически всем кандидатам была знакома эта аббревиатура. Однако пытаясь рассказать подробнее, почти все разработчики указывали в основном на то, что это стандарт оформления кода (code style). Только некоторые упоминали про PSR-4 автозагрузку (использует Composer) и PSR-3 Logger Interface (в сети очень много однородных статей про PSR-0-1-2-3-4).
Мне кажется это весьма странным, так как термин PSR существует достаточно давно (уже более 10 лет) и каждый год набирает все большую популярность. Поэтому, думаю, будет неплохо собрать все в кучу и сделать обзор PSR стандартов.
PHP-FIG и PSR
PHP-FIG (PHP Framework Interop Group) — организованная в 2009 году группа разработчиков, основная идея которой находить способы совместной работы, выделяя общие концепции в разработке проектов на PHP.
Проще говоря, ребята стараются выделить что-то общее между различными проектами на разных фреймворках и сформировать некие стандарты (рекомендации) для дальнейшего периспользования.
Участники PHP-FIG
ReactPHP, Composer, Laminas Project (переименованный Zend Framework), Yii framework, CakePHP, Slim, Joomla, Magento, Drupal, phpBB, phpDocumentor и другие.
PSR (PHP Standards Recommendations) — описывает общие концепции, которые уже были проверены и отработаны. Вероятно при создании PSR, группа PHP-FIG вдохновлялась Java Community Process, а первый стандарт был принят в 2010 году.
Список PSR стандартов расширяется новыми, а сами стандарты делятся на категории:
Автозагрузка, Интерфейсы, HTTP и Стиль кодирования,
каждому из которых присваивается определенный статус:
Принят, Устаревший, Черновик и Заброшенный.
Далее мы рассмотрим принятые PSR стандарты по категориям:
Автозагрузка
Разработчики, которые «недолго» работают с PHP, вероятно не знакомы с проблемами импорта классов, ведь есть пространства имен, а сейчас вообще трудно представить проект без менеджера зависимостей Composer, которой решает все вопросы с автозагрузкой классов.
Однако так было не всегда, пространства имен появились только в PHP 5.3 (это был 2009 год), а первый релиз Composer состоялся в марте 2012 года. Но вот сам PHP существует гораздо дольше, как Personal Home Page с 1995 года и как Hypertext Preprocessor с 1998 года, однако только PHP 5 включает «полноценную объектную модель», релиз которого был в июле 2004 года. Бородатым разработчикам того времени приходилось как-то сражаться со всеми возникшими проблемами при импорте классов.
Не самый плохой пример импорта классов на PHP 14-ти летней давности:
(Напишите в комментариях, если узнали где использовался данный подход).
В дополнение, оставлю ссылку на статью, которая подробно описывает работу с пространством имен, решенные проблемы и PSR-4.
Интерфейсы
PHP развивается, набирает все большую популярность, а его инфраструктура пополняется огромным количеством различных инструментов.
Появляются проблемы с изучением и переиспользованием однотипного функционала, а менеджер зависимостей может затянуть целую кучу несвязанных однотипных зависимостей. (тут JavaScript разработчик улыбнется).
Поэтому принято решение стандартизировать некоторые общие концепции:
Если Ваш проект нуждается в расширенном функционале, МОЖНО расширять данный интерфейс, но СЛЕДУЕТ сохранять совместимость с описанными в данном стандарте правилами. Это позволит сторонним библиотекам, применяемых при разработке приложения, использовать централизованную систему логирования.
Это привело к ситуации, когда многие библиотеки реализуют свои собственные системы кэширования с различными уровнями функциональности. Эти различия заставляют разработчиков изучать несколько систем, которые могут предоставлять или не предоставлять необходимую им функциональность. Кроме того, разработчики кеширующих библиотек сами сталкиваются с выбором между поддержкой только ограниченного числа платформ или созданием большого количества классов адаптеров.
Чтобы решить эти проблемы был принят общий стандарт для библиотек реализующих кэширование, он включает в себя несколько интерфейсов:
Пользователи НЕ ДОЛЖНЫ передавать контейнер в объект, чтобы объект мог получить свои собственные зависимости. Это означает, что контейнер используется в качестве Service Locator, который обычно не рекомендуется использовать.
Отсюда, возникает простой вопрос: «Как это вообще работает»?
На самом деле все просто, на помощь приходит паттерн Factory, который возьмет на себя задачу создания объекта. А вот сам класс фабрики уже может принимать ContainerInterface и передавать в создаваемый объект необходимые зависимости.
Поэтому был принят PSR-16. Этот более простой подход направлен на создание стандартизированного оптимизированного интерфейса для общих случаев.
В списке реализаций все тот-же Symfony Cache и Laminas Cache (бывший Zend).
Если речь идет о WEB-приложении, то не важно на сколько сложная в нем бизнес-логика, по факту оно делает всего 2 вещи — принимает Request и отдает Response. Это значит, что так или иначе, приходится реализовывать эти объекты у себя в проекте.
Пожалуй, одной из самых сложных задач, которая нередко возникает является переиспользование кода между различными проектами. Если хорошо абстрагированные участки бизнес логики, некоторые компоненты и модули перенести возможно (с минимальными затратами), то с переносом более высокого уровня фреймворков (например контроллеров) возникают сложности.
Группа PHP-FIG пытается исправить данную проблему и предоставляет стандарты абстракции над HTTP.
А более детальное описание с примерами можно разобрать в статье «PSR-7 в примерах».
Если не вдаваться во все тонкости, то по сути это возможность писать некие абстрактные контроллеры для последующего переиспользования между различными проектами.
PSR-7 не содержит рекомендации о том, как создавать HTTP-объекты. Это может приводить к трудностям при необходимости их создания внутри компонентов, которые не привязаны к конкретной реализации PSR-7.
Интерфейсы, описанные в этой спецификации, описывают методы, с помощью которых можно создавать PSR-7 объекты.
Это может сделать библиотеки более пригодными для повторного использования, так как уменьшает количество зависимостей и снижает вероятность конфликтов версий.
Также в спецификации указано, что HTTP-клиенты могут быть заменены согласно принципу подстановки Лисков. Это означает, что все клиенты ДОЛЖНЫ вести себя одинаково при отправке запроса.
Пример реализации PSR-18 можно увидеть в библиотеке Symfony HTTP-client.
Предложенная абстракция над HTTP — это весьма серьезная заявка на попытку реализовывать действительно переиспользуемые и не зависящие от конкретных библиотек и фреймворков полноценные решения.
На практике, конечно все на много сложнее и есть свои нюансы и подводные камни, однако PHP-FIG делает значительный шаг вперед в этом направлении.
Стиль кодирования
До появления стандартов стиля кодирования, каждый из разработчиков оформлял свой код по-разному: одни писали CLASSNAME, другие ClassName, а третьи Class_Name, вечный спор относительно табов и пробелов, а еще StudlyCaps vs сamelCase vs snake_case и так далее.
Цель следующих PSR стандартов уменьшить когнитивное искажение при чтении кода от разных авторов.