Расширенное руководство по стилю кодирования
Обзор
Это руководство дополняет, расширяет и заменяет PSR-2 (руководство по стилю кодирования) и требует соблюдения PSR-1 (основного стандарта кодирования).
Как и PSR-2, цель этой спецификации состоит в том, чтобы снизить сложности восприятия кода, написанного разными авторами; она достигается путём рассмотрения серии правил и ожиданий относительно форматирования PHP-кода. Стилистические правила, представленные здесь, получены путём обобщения опыта различных проектов. Сотрудничество многих авторов из многих проектов позволяет выработать единый набор принципов и использовать его в этих проектах. Таким образом, польза представленных рекомендаций – не столько в самих рекомендациях, сколько в их распространении.
PSR-2 был принят в 2012 году, и с тех пор в PHP был внесен ряд изменений, что накладывает подолнительные рекомендации на стиль кодирования. Данный PSR направлен на уточнение содержания PSR-2 в более современном контексте с новыми доступными функциями и возможностями.
Предыдущие языковые версии
В этом документе любые инструкции МОГУТ быть проигнорированы, если они отсутсвуют в вашем проекте.
Пример
Этот пример включает в себя некоторые из приведенных ниже правил в качестве краткого обзора:
<?php
declare(strict_types=1);
namespace Vendor\Package;
use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use function Vendor\Package\{functionA, functionB, functionC};
use const Vendor\Package\{ConstantA, ConstantB, ConstantC};
class Foo extends Bar implements FooInterface
{
public function sampleFunction(int $a, int $b = null): array
{
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.
Термин «StudlyCaps» в PSR-1 ДОЛЖЕН интерпретироваться как PascalCase, где первая буква каждое слово пишется с заглавной буквы, включая самую первую букву.
2.2 Файлы
Во всех файлах с PHP-кодом ДОЛЖЕН быть использован Unix-вариант переноса строк (Unix linefeed, т.е. \n
).
В конце каждого файла с PHP-кодом ДОЛЖНА быть одна пустая строка.
Закрывающий тег ?>
ДОЛЖЕН отсутствовать в файлах, содержащих только PHP-код.
2.3 Строки
НЕ ДОЛЖНО быть жестких ограничений на длину строки.
Мягкое ограничение длины строки ДОЛЖНО составлять 120 символов; автоматические проверки стиля ДОЛЖЕН предупреждать, но НЕ ДОЛЖЕН выдавать ошибку при мягком пределе.
Строки НЕ ДОЛЖНЫ быть длиннее 80 символов; строки длиннее этого ДОЛЖНЫ быть разбит на несколько последовательных строк не более 80 символов каждая.
НЕ ДОЛЖНЫ быть пробелы в конце непустых строк.
Пустые строки МОГУТ быть добавлены для улучшения удобочитаемости и для обозначения связанных блоки кода.
НЕ ДОЛЖНО быть более одного оператора в строке.
2.4 Отступы
Код ДОЛЖЕН использовать отступ в 4 пробела и НЕ ДОЛЖЕН использовать табуляцию для отступа.
2.5 Ключевые слова и типы
Все зарезервированные ключевые слова и типы PHP [1][2] ДОЛЖНЫ быть в нижнем регистре.
Любые новые типы и ключевые слова, добавленные в будущие версии PHP, ДОЛЖНЫ быть в нижнем регистре.
ДОЛЖНА использоваться краткая форма ключевых слов типа, т. е. bool
вместо boolean
,
int
вместо integer
и т. д.
3. Операторы объявления, пространство имен и операторы импорта
Заголовок файла PHP может состоять из нескольких разных блоков. Каждый из блоков ДОЛЖЕН быть разделен одной пустой строкой и НЕ ДОЛЖЕН содержать пустую строку. Каждый блок ДОЛЖЕН располагаться в порядке, указанном на на примере ниже. Неактуальные могут быть опущены.
- Открывающий тег
<?php
. - Докблок на уровне файла.
- Один или несколько операторов объявления.
- Объявление пространства имен файла.
- Один или несколько операторов импорта
use
на основе класса. - Один или несколько операторов импорта
use
на основе функций. - Один или несколько операторов импорта
use
на основе констант. - Остальной код в файле.
Когда файл содержит смесь HTML и PHP, любой из вышеперечисленных разделов может по-прежнему использоваться. Если это так, они ДОЛЖНЫ присутствовать в начале файла, даже если оставшаяся часть кода состоит из закрывающего тега PHP, а затем опять идет код в виде HTML и PHP.
Когда открывающий тег <?php
находится в первой строке файла, он ДОЛЖЕН быть на строке без других операторов,
если только это не файл, содержащий разметку вне PHP открывающие и закрывающие теги.
Операторы импорта НЕ ДОЛЖНЫ начинаться с обратной косой черты, поскольку они всегда должны быть полностью квалифицированы.
Следующий пример иллюстрирует полный список всех блоков:
<?php
/**
* Этот файл содержит пример стилей кодирования.
*/
declare(strict_types=1);
namespace Vendor\Package;
use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use Vendor\Package\AnotherNamespace\ClassE as E;
use function Vendor\Package\{functionA, functionB, functionC};
use function Another\Vendor\functionD;
use const Vendor\Package\{CONSTANT_A, CONSTANT_B, CONSTANT_C};
use const Another\Vendor\CONSTANT_D;
/**
* FooBar класс как пример.
*/
class FooBar
{
// ... остальной PHP код ...
}
НЕ ДОЛЖНЫ использоваться составные пространства имен с глубиной более двух. Ниже приведена максимально допустимая глубина вложенности:
<?php
use Vendor\Package\SomeNamespace\{
SubnamespaceOne\ClassA,
SubnamespaceOne\ClassB,
SubnamespaceTwo\ClassY,
ClassZ,
};
Такое недопустимо:
<?php
use Vendor\Package\SomeNamespace\{
SubnamespaceOne\AnotherNamespace\ClassA,
SubnamespaceOne\ClassB,
ClassZ,
};
При желании объявить строгие типы в файлах, содержащих разметку не только PHP, открывающий и закрывающий теги ДОЛЖНЫ быть в первой строке файла. Например:
<?php declare(strict_types=1) ?>
<html>
<body>
<?php
// ... дополнительный PHP код ...
?>
</body>
</html>
Операторы объявления ДОЛЖНЫ быть точно declare (strict_types=1)
(с необязательной точкой и запятой).
Операторы объявления блока разрешены и ДОЛЖНЫ быть отформатированы, как показано ниже. Обратите внимание на положение фигурных скобок и интервал:
declare(ticks=1) {
// некоторый код
}
4. Классы, свойства и методы
Здесь под «классом» следует понимать также интерфейсы (interface
) и примеси (trait
).
За любой закрывающей фигурной скобкой НЕ ДОЛЖНО быть никакого комментария или выражения.
При создании экземпляра нового класса круглые скобки ДОЛЖНЫ присутствовать всегда, даже если в конструктор не передаются аргументы.
Например:
new Foo();
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 Использование трейдов
Ключевое слово use
, используемое внутри классов для реализации трейтов, ДОЛЖНО быть
объявляется на следующей строке после открывающей скобки.
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
}
Каждый отдельный трейт, который импортируется в класс, ДОЛЖЕН быть включен
по одному на строку, и каждое включение ДОЛЖНО иметь свой собственный оператор импорта use
.
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
use Vendor\Package\SecondTrait;
use Vendor\Package\ThirdTrait;
class ClassName
{
use FirstTrait;
use SecondTrait;
use ThirdTrait;
}
Когда в классе нет ничего после оператора импорта use
,
закрывающая фигурная скобка ДОЛЖНА быть на следующей строке после оператора импорта use
.
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
}
В противном случае он ДОЛЖЕН иметь пустую строку после оператора импорта use
.
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
private $property;
}
При использовании операторов insteadof
и as
они должны быть как на примере ниже.
Обратите внимание на отступы, пробелы, переносы строк.
<?php
class Talker
{
use A;
use B {
A::smallTalk insteadof B;
}
use C {
B::bigTalk insteadof C;
C::mediumTalk as FooBar;
}
}
4.3 Свойства и константы
Видимость ДОЛЖНА быть объявлена для всех свойств.
Видимость ДОЛЖНА быть объявлена для всех констант, если ваш проект на PHP 7.1 или новее.
Ключевое слово var
НЕ ДОЛЖНО использоваться для объявления свойства.
В инструкции НЕ ДОЛЖНО быть объявлено более одного свойства.
Имена свойств НЕ ДОЛЖНЫ иметь префикс с одним подчеркиванием, чтобы указать защищенная или частная видимость.
ДОЛЖЕН быть пробел между объявлением типа и именем свойства.
Объявление свойства выглядит следующим образом:
<?php
namespace Vendor\Package;
class ClassName
{
public $foo = null;
public static int $bar = 0;
}
4.4 Методы и функции
Видимость ДОЛЖНА быть объявлена для всех методов.
Имена методов НЕ ДОЛЖНЫ иметь префикс с одним подчеркиванием, чтобы указать защищенная или частная видимость.
Имена методов и функций НЕ ДОЛЖНЫ объявляться с пробелом после имени метода. Открывающая фигурная скобка ДОЛЖНА располагаться на отдельной строке, а закрывающая скобка ДОЛЖНА располагаться на следующей строке после тела метода. НЕ ДОЛЖНО быть пробела после открывающей скобки и НЕ ДОЛЖНО быть пробела перед закрывающей скобкой.
Объявление метода выглядит следующим образом. Обратите внимание на расположение круглых скобок, запятых, пробелов и фигурных скобок:
<?php
namespace Vendor\Package;
class ClassName
{
public function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// тело метода
}
}
Объявление функции выглядит следующим образом. Обратите внимание на расположение круглых скобок, запятых, пробелов и фигурных скобок:
<?php
function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// тело метода
}
4.5 Аргументы методов и функций
В списке аргументов НЕ ДОЛЖНО быть пробела перед запятыми, но ДОЛЖЕН быть пробел после каждой запятой.
Аргументы со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию). {Примечание: и тут дело не в красоте, нарушение этого правила может привести ко вполне явным ошибкам выполнения программы, когда аргументу без значения по умолчанию «не хватит» значения при вызове метода.}
<?php
namespace Vendor\Package;
class ClassName
{
public function foo(int $arg1, &$arg2, $arg3 = [])
{
// тело метода
}
}
Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.
В случае, если список аргументов разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться вместе на своей отдельной строке, а между ними должен быть один пробел.
<?php
namespace Vendor\Package;
class ClassName
{
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
array $arg3 = []
) {
// тело метода
}
}
Если у вас есть объявление возвращаемого типа, ДОЛЖЕН быть один пробел после двоеточия, за которым следует объявление типа. Двоеточие и объявление ДОЛЖНЫ находиться в той же строке, что и закрывающая скобка списка аргументов, без пробелов между двумя символами.
<?php
declare(strict_types=1);
namespace Vendor\Package;
class ReturnTypeVariations
{
public function functionName(int $arg1, $arg2): string
{
return 'foo';
}
public function anotherFunction(
string $foo,
string $bar,
int $baz
): string {
return 'foo';
}
}
В объявлениях типов, допускающих значение null, НЕ ДОЛЖНО быть пробела между знаком вопроса и типом.
<?php
declare(strict_types=1);
namespace Vendor\Package;
class ReturnTypeVariations
{
public function functionName(?string $arg1, ?int &$arg2): ?string
{
return 'foo';
}
}
При использовании оператора ссылки &
перед аргументом НЕ ДОЛЖНО быть пробела, как в предыдущем примере.
НЕ ДОЛЖНО быть пробела между вариативным оператором с тремя точками и именем аргумента:
public function process(string $algorithm, ...$parts)
{
// обработка
}
При объединении ссылочного оператора и вариативного оператора с тремя точками между ними НЕ ДОЛЖНО быть пробела:
public function process(string $algorithm, &...$parts)
{
// processing
}
4.6 Ключевые слова 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.7 Вызовы методов и функций
В коде вызова функций и методов НЕ ДОЛЖНО быть пробела между именем функции или метода и открывающей круглой скобкой, НЕ ДОЛЖНО быть пробела после открывающей круглой скобки, НЕ ДОЛЖНО быть пробела перед закрывающей круглой скобкой. В списке аргументов НЕ ДОЛЖНО быть пробелов перед запятыми, но ДОЛЖЕН быть пробел после каждой запятой.
<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.
<?php
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
<?php
somefunction($foo, $bar, [
// ...
], $baz);
$app->get('/hello/{name}', function ($name) use ($app) {
return 'Hello ' . $app->escape($name);
});
5. Управляющие конструкции
Общие правила оформления управляющих конструкций:
- После ключевого слова, определяющего управляющую конструкцию, ДОЛЖЕН быть один пробел.
- После открывающих круглых скобок НЕ ДОЛЖНО быть пробелов.
- Перед закрывающими круглыми скобками НЕ ДОЛЖНО быть пробелов.
- Между закрывающей круглой скобкой и открывающей фигурной скобкой ДОЛЖЕН быть один пробел.
- Тело конструкции ДОЛЖНО быть дополнено одним отступом (четырьмя пробелами).
- Закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела конструкции.
The body of each structure MUST be enclosed by braces. This standardizes how the structures look and reduces the likelihood of introducing errors as new lines get added to the body.
5.1 Конструкции if
, elseif
, else
Конструкция if
выглядит следующим образом.
Обратите внимание на круглые скобки, пробелы и фигурные скобки, а также на тот факт,
что слова else
и elseif
располагаются в той же строке,
что и закрывающая фигурная скобка предшествующего тела конструкции.
<?php
if ($expr1) {
// if блок
} elseif ($expr2) {
// elseif блок
} else {
// else блок
}
Ключевое слово elseif
СЛЕДУЕТ использовать вместо отдельного сочетания else
и if
.
Так конструкция будет представлять собой одно слово.
Выражения в круглых скобках МОГУТ быть разделены на несколько строк, где каждая последующая строка имеет отступ хотя бы один раз. При этом первое условие ДОЛЖНО быть на следующей строке. Закрывающая скобка и открывающая фигурная скобка ДОЛЖНЫ быть помещены вместе на отдельной строке с одним пробелом между ними. Булевы операторы между условиями ДОЛЖНЫ всегда находиться в начале или в конце строки, а не в сочетании того и другого.
<?php
if (
$expr1
&& $expr2
) {
// if блок
} elseif (
$expr3
&& $expr4
) {
// elseif блок
}
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;
}
Выражения в круглых скобках МОГУТ быть разделены на несколько строк, где каждая последующая строка имеет отступ хотя бы один раз. При этом первое условие ДОЛЖНО быть на следующей строке. Закрывающая скобка и открывающая фигурная скобка ДОЛЖНЫ быть помещены вместе на отдельной строке с одним пробелом между ними. Булевы операторы между условиями ДОЛЖНЫ всегда находиться в начале или в конце строки, а не в сочетании того и другого.
<?php
switch (
$expr1
&& $expr2
) {
// тело цикла
}
5.3 Конструкции while
, do while
Конструкция while
выглядит следующим образом.
Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?php
while ($expr) {
// тело цикла
}
Выражения в круглых скобках МОГУТ быть разделены на несколько строк, где каждая последующая строка имеет отступ хотя бы один раз. При этом первое условие ДОЛЖНО быть на следующей строке. Закрывающая скобка и открывающая фигурная скобка ДОЛЖНЫ быть помещены вместе на отдельной строке с одним пробелом между ними. Булевы операторы между условиями ДОЛЖНЫ всегда находиться в начале или в конце строки, а не в сочетании того и другого.
<?php
while (
$expr1
&& $expr2
) {
// тело цикла
}
Соответственно, конструкция do while
выглядит следующим образом.
Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?php
do {
// тело цикла
} while ($expr);
Выражения в круглых скобках МОГУТ быть разделены на несколько строк, где каждая последующая строка имеет отступ хотя бы один раз. При этом первое условие ДОЛЖНО быть на следующей строке. Булевы операторы между условиями ДОЛЖНЫ всегда находиться в начале или в конце строки, а не в сочетании того и другого.
<?php
do {
// тело метода
} while (
$expr1
&& $expr2
);
5.4 Конструкция for
Конструкция for
выглядит следующим образом.
Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?php
for ($i = 0; $i < 10; $i++) {
// тело цикла
}
Выражения в круглых скобках МОГУТ быть разделены на несколько строк, где каждая последующая строка имеет отступ хотя бы один раз. При этом первое условие ДОЛЖНО быть на следующей строке. Булевы операторы между условиями ДОЛЖНЫ всегда находиться в начале или в конце строки, а не в сочетании того и другого.
<?php
for (
$i = 0;
$i < 10;
$i++
) {
// тело цикла
}
5.5 Конструкция foreach
Конструкция foreach
выглядит следующим образом.
Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?php
foreach ($iterable as $key => $value) {
// тело цикла
}
5.6 Конструкции try
, catch
, finally
Блок try-catch-finally
выглядит следующим образом. Обратите внимание на расположение
круглых скобок, пробелов и фигурных скобок.
<?php
try {
// try блок
} catch (FirstThrowableType $e) {
// catch блок
} catch (OtherThrowableType | AnotherThrowableType $e) {
// catch блок
} finally {
// finally блок
}
6. Операторы
Правила стиля для операторов сгруппированы по количеству операндов, которые они принимают.
Когда вокруг оператора разрешено пространство, МОЖЕТ быть несколько пробелов. Используется для удобства чтения.
Все операторы, не описанные здесь, остаются неопределенными.
6.1. Унарные операторы
Операторы инкремента/декремента НЕ ДОЛЖНЫ иметь пробела между оператором и операндом.
$i++;
++$j;
Операторы приведения типов НЕ ДОЛЖНЫ иметь пробелов в круглых скобках:
$intValue = (int) $input;
6.2. Бинарные операторы
Все бинарные arithmetic, comparison, assignment, bitwise, logical, string, type операторы ДОЛЖНЫ предшествоваться и сопровождаться по крайней мере одним пробелом:
if ($a === $b) {
$foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
$foo = $a + $b * $c;
}
6.3. Тернарные операторы
Перед условным оператором, также известным как тернарный оператор,
ДОЛЖЕН стоять хотя бы один пробел вокруг символов ?
и :
:
$variable = $foo ? 'foo' : 'bar';
Когда средний операнд условного оператора опущен, оператор ДОЛЖЕН следовать тем же правилам стиля, что и другие бинарные comparison операторы:
$variable = $foo ?: 'bar';
7. Замыкания
- Замыкания ДОЛЖНЫ описываться с использованием пробела после ключевого слова
function
и пробелами до и после ключевого словаuse
. - Открывающая фигурная скобка ДОЛЖНА располагаться на одной строке с именем замыкания строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела замыкания.
- После открывающей круглой скобки и перед закрывающей круглой скобкой в списке аргументов или переменных НЕ ДОЛЖНО быть пробела.
- В списке аргументов или переменных НЕ ДОЛЖНО быть пробелов перед запятыми, но ДОЛЖЕН быть один пробел после каждой запятой.
- Аргументы замыкания со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию).
Описание замыкания выглядит следующим образом. Обратите внимание на круглые скобки, запятые, пробелы и фигурные скобки.:
<?php
$closureWithArgs = function ($arg1, $arg2) {
// тело замыкания
};
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// тело замыкания
};
$closureWithArgsVarsAndReturn = function ($arg1, $arg2) use ($var1, $var2): bool {
// тело замыкания
};
Список аргументов и переменных МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один элемент.
Когда последний список (аргументов или переменных) разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться на одной строке и быть разделены одним пробелом.
Ниже представлены примеры замыканий со списком аргументов и без него, а также со списком переменных, располагающимся на нескольких строках.
<?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
);
8. Анонимные классы
Анонимные классы ДОЛЖНЫ следовать тем же правилам и принципам, что и замыкания в предыдущем разделе.
<?php
$instance = new class {};
Открывающая фигурная скобка МОЖЕТ находиться в той же строке, что и ключевое слово class
,
если список интерфейсов implements
не переносится.
Если список интерфейсов переносится, фигурная скобка ДОЛЖНА быть помещена в строку сразу после последнего интерфейса.
<?php
// Скобки на той же линии
$instance = new class extends \Foo implements \HandleableInterface {
// Содержание класса
};
// Скобки на следующей линии
$instance = new class extends \Foo implements
\ArrayAccess,
\Countable,
\Serializable
{
// Содержание класса
};