Руководство по стилю кодирования
Устарело — по состоянию на 10 августа 2019 г. PSR-2 помечен как устаревший. PSR-12 теперь рекомендуется как альтернатива.
Это руководство расширяет и дополняет PSR-1, базовый стандарт кодирования.
Цель этого руководства — уменьшить трения при разборе кода от разных авторов. Это достигается путем перечисления общего набора правил и ожидания относительно того, как форматировать PHP-код.
Приведенные здесь правила стиля основаны на общих чертах различных участников. Когда разные авторы сотрудничают в нескольких проектах, это помогает иметь один набор руководящих принципов, которые будут использоваться во всех этих проектах. Таким образом польза от этого руководства не в самих правилах, а в обмене этими правила.
Ключевые слова «ДОЛЖЕН», «НЕ ДОЛЖЕН», «ТРЕБУЕТСЯ», «СЛЕДУЕТ», "РЕКОМЕНДУЕТСЯ", "МОЖЕТ" и "ДОПОЛНИТЕЛЬНО" в этом документе должны быть интерпретированы как описано в RFC 2119.
1. Обзор
-
Код ДОЛЖЕН следовать «руководству по стилю кодирования» PSR-1.
-
Код ДОЛЖЕН использовать 4 пробела для отступа, а не табуляции.
-
НЕ ДОЛЖНО быть жестких ограничений на длину строки; мягкое ограничение ДОЛЖНО быть 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 sampleMethod($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 LF (перевод строки).
Все файлы PHP ДОЛЖНЫ заканчиваться одной пустой строкой.
Закрывающий тег ?>
ДОЛЖЕН быть опущен в файлах, содержащих только PHP.
2.3. Строки
НЕ ДОЛЖНО быть жестких ограничений на длину строки.
Мягкое ограничение длины строки ДОЛЖНО составлять 120 символов; автоматические проверки стиля ДОЛЖЕН предупреждать, но НЕ ДОЛЖЕН выдавать ошибку при мягком пределе.
Строки НЕ ДОЛЖНЫ быть длиннее 80 символов; строки длиннее этого ДОЛЖНЫ быть разбит на несколько последовательных строк не более 80 символов каждая.
НЕ ДОЛЖНЫ быть пробелы в конце непустых строк.
Пустые строки МОГУТ быть добавлены для улучшения удобочитаемости и для обозначения связанных блоки кода.
НЕ ДОЛЖНО быть более одного оператора в строке.
2.4. Отступы
Код ДОЛЖЕН использовать отступ в 4 пробела и НЕ ДОЛЖЕН использовать табуляцию для отступа.
N.b.: использование только пробелов и отказ от смешивания пробелов с табуляциями помогает избежать Проблемы с дифами, патчами, историей и аннотациями. Использование пробелов также позволяет легко вставлять мелкие отступы для межстрочного выравнивание.
2.5. Ключевые слова и True/False/Null
Ключевые слова (keywords) ДОЛЖНЫ быть в нижнем регистре.
PHP константы true
, false
, и null
ДОЛЖНЫ быть в нижнем регистре.
3. Пространства имен и блоки импорта
Если присутствует пространство имен, ДОЛЖНА быть одна пустая строка после объявления namespace
.
При наличии все объявления use
ДОЛЖНЫ идти после объявления namespace
В каждом объявлении ДОЛЖНО быть одно ключевое слово use
.
ДОЛЖНА быть одна пустая строка после блока use
.
Например:
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
// ... другой код ...
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
{
// константы, свойства, методы
}
Список реализуемых интерфейсов после implements
МОГУТ быть разделены на несколько строк, где каждый
последующая строка имеет один отступ. При этом первый элемент в списке
ДОЛЖЕН быть на следующей строке, и в каждой строке ДОЛЖЕН быть только один интерфейс.
<?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
НЕ ДОЛЖНО использоваться для объявления свойства.
В инструкции НЕ ДОЛЖНО быть объявлено более одного свойства.
Имена свойств НЕ ДОЛЖНЫ иметь префикс с одним подчеркиванием, чтобы указать защищенная или частная видимость.
Объявление свойства выглядит следующим образом.
<?php
namespace Vendor\Package;
class ClassName
{
public $foo = null;
}
4.3. Методы
Область видимости ДОЛЖНА быть объявлена для всех методов.
Имена методов НЕ ДОЛЖНЫ иметь префикс с одним подчеркиванием, чтобы указать защищенная или частная видимость.
Имена методов НЕ ДОЛЖНЫ объявляться с пробелом после имени метода. Открывающая фигурная скобка ДОЛЖНА располагаться на отдельной строке, а закрывающая скобка ДОЛЖНА располагаться на следующей строке после тела метода. НЕ ДОЛЖНО быть пробела после открытия скобки, и НЕ ДОЛЖНО быть пробела перед закрывающей скобкой.
Объявление метода выглядит следующим образом. Обратите внимание на размещение круглых скобок, запятых, пробелов и фигурных скобок:
<?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);
Списки аргументов МОГУТ быть разделены на несколько строк, где каждая последующая строка имеет только один отступ. При этом первый элемент в списке ДОЛЖЕН находиться на следующей строке, и на каждой строке ДОЛЖЕН быть только один аргумент.
<?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
. ДОЛЖЕН быть комментарий типа
// no break
, когда это сделано намеренно в непустом теле case
.
<?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++) {
// тело цикла
}
5.5. Управляющая конструкция foreach
Оператор foreach
выглядит следующим образом. Обратите внимание на размещение
круглые скобок, пробелов и фигурных скобок.
<?php
foreach ($iterable as $key => $value) {
// тело цикла
}
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. Заключение
Здесь намеренно опущены многие элементы стиля и практики руководства. К ним относятся, но не ограничиваются:
-
Объявление глобальных переменных и глобальных констант
-
Объявление функций
-
Операторы и присваивание
-
Межстрочное выравнивание
-
Блоки комментариев и документации
-
Префиксы и суффиксы имени класса
-
Лучшие практики
Будущие рекомендации МОГУТ пересматривать и расширять это руководство для решения тех или иных проблем.