MyTetra Share
Делитесь знаниями!
О, смотри-ка какое хорошее место. Дайте два!
PSR-2 – Рекомендации по оформлению кода
13.04.2017
17:03
Текстовые метки: php, psr, psr-2, psr2, psr 2, стандарт
Раздел: Компьютер - Программирование - Язык PHP

PSR-2 – Рекомендации по оформлению кода

Данные рекомендации расширяют и дополняют базовый стандарт оформления кода PSR-1.

Цель данных рекомендаций – снижение сложности восприятия кода, написанного разными авторами; она достигается путём рассмотрения серии правил и ожиданий относительно форматирования PHP-кода.

Стилистические правила, представленные здесь, получены путём обобщения опыта различных проектов. Сотрудничество многих авторов из многих проектов позволяет выработать единый набор принципов и использовать его в этих проектах. Таким образом, польза представленных рекомендаций – не столько в самих рекомендациях, сколько в их распространении.

Слова «НЕОБХОДИМО» / «ДОЛЖНО» («MUST»), «НЕДОПУСТИМО» («MUST NOT»), «ТРЕБУЕТСЯ» («REQUIRED»), «НУЖНО» («SHALL»), «НЕ ПОЗВОЛЯЕТСЯ» («SHALL NOT»), «СЛЕДУЕТ» («SHOULD»), «НЕ СЛЕДУЕТ» («SHOULD NOT»), «РЕКОМЕНДУЕТСЯ» («RECOMMENDED»), «МОЖЕТ» / «ВОЗМОЖНО» («MAY») и «НЕОБЯЗАТЕЛЬНО» («OPTIONAL») в этом документе следует понимать так, как это описано в RFC 2119 (и его переводе).

1. Общие положения

  • Код ДОЛЖЕН быть оформлен согласно стандарту PSR-1.
  • Для оформления отступов ДОЛЖНЫ использоваться четыре пробела (но не знак табуляции).
  • НЕДОПУСТИМО жёстко ограничивать длину строки; мягкое ограничение ДОЛЖНО составлять 120 символов; СЛЕДУЕТ стараться, чтобы длина строки составляла 80 символов или менее.
  • После определения пространства имён (namespace) и после блока импорта пространств имён (use) ДОЛЖНА быть одна пустая строка.
  • Открывающая фигурная скобка в определении класса ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела класса.
  • Открывающая фигурная скобка в определении метода ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела метода.
  • Область видимости ДОЛЖНА быть указана явно для всех свойств и методов; модификаторы abstract и final ДОЛЖНЫ располагаться перед модификаторами области видимости; модификатор static ДОЛЖЕН располагаться после модификаторов области видимости.
  • После ключевых слов в управляющих конструкциях ДОЛЖЕН располагаться один пробел, а после вызовов функций и методов – НЕ ДОЛЖЕН.
  • Открывающая фигурная скобка в управляющих конструкциях ДОЛЖНА располагаться в той же строке, что и сама конструкция, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела конструкции.
  • После открывающей круглой скобки и перед закрывающей круглой скобкой в управляющих конструкциях НЕ ДОЛЖНО быть пробела.

1.1. Пример

Следующий пример охватывает часть из вышеописанных правил:

<?php

 

namespace Vendor\Package;

 

use FooInterface;

use BarClass as Bar;

use OtherVendor\OtherPackage\BazClass;

 

class Foo extends Bar implements FooInterface

{

    public function sampleFunction($a, $b = null)

    {

        if ($a === $b) {

            bar();

        } elseif ($a > $b) {

            $foo->bar($arg1);

        } else {

            BazClass::bar($arg2, $arg3);

        }

    }

 

    final public static function bar()

    {

        // тело метода

    }

}


2. Основные положения

2.1. Базовый стандарт оформления кода

Код ДОЛЖЕН быть оформлен согласно всем правилам, указанным в стандарте PSR-1.

2.2. Файлы

  • Во всех файлах с PHP-кодом ДОЛЖЕН быть использован Unix-вариант переноса строк (Unix linefeed, т.е. \n).
  • В конце каждого файла с PHP-кодом ДОЛЖНА быть одна пустая строка.
  • Закрывающий тег ?> ДОЛЖЕН отсутствовать в файлах, содержащих только PHP-код.

2.3. Строки

  • НЕ ДОЛЖНО быть жёсткого ограничения длины строки.
  • Мягкое ограничение длины строки ДОЛЖНО составлять 120 символов; автоматические системы проверки стиля ДОЛЖНЫ выдавать предупреждение при превышении этого ограничения, но НЕ ДОЛЖНЫ считать это ошибочной ситуацией.
  • СЛЕДУЕТ стараться, чтобы длина строки составляла 80 символов или менее; более длинные строки СЛЕДУЕТ разбивать на несколько отдельных строк, длина каждой из которых не превышала бы 80 символов.
  • В конце непустых строк НЕ ДОЛЖНО быть пробелов.
  • Пустые строки МОГУТ быть добавлены в код для повышения удобочитаемости и разделения блоков кода.
  • В одной строке НЕ ДОЛЖНО быть более одного выражения.

2.4. Отступы

Для оформления отступов ДОЛЖНЫ использоваться четыре пробела (но не знак табуляции).

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

2.5. Ключевые слова и константы true / false / null

  • Ключевые слова PHP ДОЛЖНЫ быть написаны в нижнем регистре.
  • Константы PHP true, false и null ДОЛЖНЫ быть написаны в нижнем регистре.

3. Определение пространств имён и блоков импорта

  • В случае наличия определения пространства имён, после него ДОЛЖНА располагаться одна пустая строка.
  • В случае наличия импорта пространств имён, он ДОЛЖЕН располагаться после определения пространства имён.
  • При реализации импорта каждое пространство имён ДОЛЖНО импортироваться отдельно (со своим ключевым словом use).
  • После блока импорта ДОЛЖНА быть одна пустая строка.

Пример:

<?php

 

namespace Vendor\Package;

 

use FooClass;

use BarClass as Bar;

use OtherVendor\OtherPackage\BazClass;

 

// ... далее следует PHP-код ...


4. Классы, свойства и методы

Здесь под «классом» следует понимать также интерфейсы (interface) и примеси (trait).

4.1. Наследование и реализация

  • Ключевые слова extends и implements ДОЛЖНЫ находиться на той же строке, на которой находится имя класса.
  • Открывающая фигурная скобка в определении класса ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела класса.


<?php

 

namespace Vendor\Package;

 

use FooClass;

use BarClass as Bar;

use OtherVendor\OtherPackage\BazClass;

 

class ClassName extends ParentClass implements \ArrayAccess, \Countable

{

    // константы, свойства, методы

}


  • Список реализуемых интерфейсов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка интерфейсов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один интерфейс.


<?php

 

namespace Vendor\Package;

 

use FooClass;

use BarClass as Bar;

use OtherVendor\OtherPackage\BazClass;

 

class ClassName extends ParentClass implements

    \ArrayAccess,

    \Countable,

    \Serializable

{

    // константы, свойства, методы

}


4.2. Свойства

  • Область видимости ДОЛЖНА быть явно указана для каждого свойства.
  • При определении свойства НЕ ДОЛЖНО применяться ключевое слово var.
  • В одном выражении НЕ ДОЛЖНО быть определено более одного свойства.
  • Одиночный знак подчёркивания в начале имени свойства НЕ СЛЕДУЕТ использовать как признак защищённой (protected) или приватной (private) области видимости.

В общем случае определение свойства выглядит так:


<?php

 

namespace Vendor\Package;

 

class ClassName

{

    public $foo = null;

}


4.3. Методы

  • Область видимости ДОЛЖНА быть явно указана для каждого метода.
  • Одиночный знак подчёркивания в начале имени метода НЕ СЛЕДУЕТ использовать как признак защищённой (protected) или приватной (private) области видимости.
  • После имени метода НЕ ДОЛЖНО быть пробела. Открывающая фигурная скобка ДОЛЖНА находиться на отдельной строке, а закрывающая фигурная скобка ДОЛЖНА находиться на следующей за телом метода строке. НЕ ДОЛЖНО быть пробелов после открывающей и перед закрывающей круглыми скобками в определении метода.

В общем случае определение метода выглядит так. Обратите внимание на круглые скобки, запятые, пробелы и фигурные скобки:


<?php

 

namespace Vendor\Package;

 

class ClassName

{

    public function fooBarBaz($arg1, &$arg2, $arg3 = [])

    {

        // тело метода

    }

}



4.4. Аргументы методов

  • В списке аргументов НЕ ДОЛЖНО быть пробела перед запятыми, но ДОЛЖЕН быть пробел после каждой запятой.
  • Аргументы со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию). {Примечание переводчика: и тут дело не в красоте, нарушение этого правила может привести ко вполне явным ошибкам выполнения программы, когда аргументу без значения по умолчанию «не хватит» значения при вызове метода.}

<?php

 

namespace Vendor\Package;

 

class ClassName

{

    public function foo($arg1, &$arg2, $arg3 = [])

    {

        // тело метода

    }

}


  • Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.
  • В случае, если список аргументов разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться вместе на своей отдельной строке, а между ними должен быть один пробел.

<?php

 

namespace Vendor\Package;

 

class ClassName

{

    public function aVeryLongMethodName(

        ClassTypeHint $arg1,

        &$arg2,

        array $arg3 = []

    ) {

        // тело метода

    }

}


4.5. Ключевые слова abstract, final и static

  • Ключевые слова abstract и final, в случае их наличия, ДОЛЖНЫ располагаться перед указанием области видимости.
  • Ключевое слово static, в случае его наличия, ДОЛЖНО располагаться после указания области видимости.


<?php

 

namespace Vendor\Package;

 

abstract class ClassName

{

    protected static $foo;

 

    abstract protected function zim();

 

    final public static function bar()

    {

        // тело метода

    }

}


4.6. Вызовы методов и функций

В коде вызова функций и методов НЕ ДОЛЖНО быть пробела между именем функции или метода и открывающей круглой скобкой, НЕ ДОЛЖНО быть пробела после открывающей круглой скобки, НЕ ДОЛЖНО быть пробела перед закрывающей круглой скобкой. В списке аргументов НЕ ДОЛЖНО быть пробелов перед запятыми, но ДОЛЖЕН быть пробел после каждой запятой.

<?php

bar();

$foo->bar($arg1);

Foo::bar($arg2, $arg3);

Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.

?

1

2

3

4

5

6

<?php

$foo->bar(

    $longArgument,

    $longerArgument,

    $muchLongerArgument

);

5. Управляющие конструкции

Общие правила оформления управляющих конструкций:

  • После ключевого слова, определяющего управляющую конструкцию, ДОЛЖЕН быть один пробел.
  • После открывающих круглых скобок НЕ ДОЛЖНО быть пробелов.
  • Перед закрывающими круглыми скобками НЕ ДОЛЖНО быть пробелов.
  • Между закрывающей круглой скобкой и открывающей фигурной скобкой ДОЛЖЕН быть один пробел.
  • Тело конструкции ДОЛЖНО быть дополнено одним отступом (четырьмя пробелами).
  • Закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела конструкции.

Тело каждой управляющей конструкции ДОЛЖНО быть заключено в фигурные скобки. Это позволяет стандартизировать внешний вид управляющих конструкций с снизить риск возникновения ошибок при добавлении новых строк в тело конструкции.

5.1. Конструкции if, elseif и else

Конструкция if выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки, а также на тот факт, что слова else и elseif располагаются в той же строке, что и закрывающая фигурная скобка предшествующего тела конструкции.

<?php

if ($expr1) {

    // тело if

} elseif ($expr2) {

    // тело elseif

} else {

    // тело else

}

Ключевое слово elseif СЛЕДУЕТ использовать вместо отдельного сочетания else и if. Так конструкция будет представлять собой одно слово.

5.2. Конструкции switch и case

Конструкция switch выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки. Выражение case ДОЛЖНО быть смещено на один отступ (четыре пробела) от switch, а ключевое слово break (или иное слово, обозначающее выход из конструкции) ДОЛЖНО располагаться на том же уровне отступов, что и тело case. В том случае, когда в непустом теле case умышленно не используется break, ДОЛЖЕН быть комментарий в стиле // no break.

<?php

switch ($expr) {

    case 0:

        echo 'First case, with a break';

        break;

    case 1:

        echo 'Second case, which falls through';

        // no break

    case 2:

    case 3:

    case 4:

        echo 'Third case, return instead of break';

        return;

    default:

        echo 'Default case';

        break;

}


5.3. Конструкции while и do while

Конструкция while выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.


<?php

while ($expr) {

    // тело конструкции

}


Соответственно, конструкция do while выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php

do {

    // тело конструкции

} while ($expr);


5.4. Конструкция for

Конструкция for выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php

for ($i = 0; $i < 10; $i++) {

    // тело for

}


5.5. Конструкция foreach

Конструкция foreach выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php

foreach ($iterable as $key => $value) {

    // тело foreach

}


5.6. Конструкция try catch

Блоки конструкции try catch выглядят следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php

try {

    // тело try

} catch (FirstExceptionType $e) {

    // тело catch

} catch (OtherExceptionType $e) {

    // тело catch

}


6. Замыкания

  • Замыкания ДОЛЖНЫ описываться с использованием пробела после ключевого слова function и пробелами до и после ключевого слова use.
  • Открывающая фигурная скобка ДОЛЖНА располагаться на одной строке с именем замыкания строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела замыкания.
  • После открывающей круглой скобки и перед закрывающей круглой скобкой в списке аргументов или переменных НЕ ДОЛЖНО быть пробела.
  • В списке аргументов или переменных НЕ ДОЛЖНО быть пробелов перед запятыми, но ДОЛЖЕН быть один пробел после каждой запятой.
  • Аргументы замыкания со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию). {Примечание переводчика: и тут дело не в красоте, нарушение этого правила может привести ко вполне явным ошибкам выполнения программы, когда аргументу без значения по умолчанию «не хватит» значения при вызове.}

Описание замыкания выглядит следующим образом. Обратите внимание на круглые скобки, запятые, пробелы и фигурные скобки.

<?php

$closureWithArgs = function ($arg1, $arg2) {

    // тело

};

 

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {

    // тело

};


Список аргументов и переменных МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один элемент.

Когда последний список (аргументов или переменных) разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться на одной строке и быть разделены одним пробелом.

Ниже представлены примеры замыканий со списком аргументов и без него, а также со списком переменных, располагающимся на нескольких строках.

<?php

$longArgs_noVars = function (

    $longArgument,

    $longerArgument,

    $muchLongerArgument

) {

   // тело

};

 

$noArgs_longVars = function () use (

    $longVar1,

    $longerVar2,

    $muchLongerVar3

) {

   // тело

};

 

$longArgs_longVars = function (

    $longArgument,

    $longerArgument,

    $muchLongerArgument

) use (

    $longVar1,

    $longerVar2,

    $muchLongerVar3

) {

   // тело

};

 

$longArgs_shortVars = function (

    $longArgument,

    $longerArgument,

    $muchLongerArgument

) use ($var1) {

   // тело

};

 

$shortArgs_longVars = function ($arg) use (

    $longVar1,

    $longerVar2,

    $muchLongerVar3

) {

   // тело

};


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

<?php

$foo->bar(

    $arg1,

    function ($arg2) use ($var1) {

        // тело

    },

    $arg3

);


7. Заключение

В этом руководстве намеренно не рассмотрены правила и лучшие практики по оформлению многих элементов, список которых включает в себя, но не ограничивается следующим:

  • Определение глобальных переменных и констант.
  • Определение функций.
  • Использование операторов и присваивание.
  • Межстрочное выравнивание.
  • Блоки комментариев и документации.
  • Префиксы и суффиксы в именах классов.
  • Лучшие практики.

В будущем данные рекомендации МОГУТ быть пересмотрены и расширены, чтобы охватить те или иные элементы кода и практики оформления.

Приложение A. Опрос

Примечание переводчика: в оригинальном тексте стандарта содержится приложение с результатами опроса, на основе которого были приняты те или иные решения. Приложение представляет собой большой массив неудобочитаемых данных и не несёт явной пользы для понимания стандарта. Вы всегда можете ознакомиться с представленными там данными здесь: http://www.php-fig.org/psr/psr-2/.


Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования