PSR-12

Declare Statements, Namespace, and Import Statements

各ブロックは以下の順序で記述する。

  • 開始タグ
  • ファイルレベルの DocBlock
  • 1つ以上の宣言ステートメント
  • ファイルの名前空間宣言
  • 1つ以上のクラスベースの use インポート文
  • 1つ以上の関数ベースの use インポート文
  • 1つ以上の定数ベースの use インポート文
  • ファイル内の残りのコード
<?php

/**
 * This file contains an example of coding styles.
 */

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 is an example class.
 */
class FooBar
{
    // ... additional PHP code ...
}

2階層以上の名前空間は使用しない。

<?php
// 許可されない
use Vendor\Package\SomeNamespace\{
    SubnamespaceOne\AnotherNamespace\ClassA,
    SubnamespaceOne\ClassB,
    ClassZ,
};

Classes, Properties, and Methods

Extends and Implements
  • extendやimplementはクラス名と同じ行で宣言する
  • クラスの開始波括弧は独自の行に配置し、前後に空白行があってはいけない
  • クラスの終了波括弧は独自の行に配置し、前に空白行があってはいけない
<?php

namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // constants, properties, methods
}
Using Traits
  • useは開始波括弧の次の行で宣言する
  • クラスにインポートされる個々のトレイトはそれぞれ独自のuse宣言が必要
  • use宣言のあとにコードが続く場合、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;

    private $property;
}
Properties and Constants
  • すべてのプロパティで可視性(private, public)を宣言する
  • PHP7.1以降、すべての定数で可視性を宣言する
  • プロパティの宣言にvarを使用しない
  • 一つのステートメントで宣言できるプロパティは一つだけ
<?php

namespace Vendor\Package;

class ClassName
{
    public $foo = null;
    public static int $bar = 0;
}
Methods and Functions
  • すべてのメソッドで可視性を宣言する
  • 開始波括弧は独自の行に配置する
  • 終了波括弧の前に空白行があってはいけない
  • 左括弧の後、右括弧の前に空白があってはいけない
Method and Function Arguments
  • 引数リストではカンマの前にスペースがあってはならず、後にスペースがなければいけない
  • デフォルト値を持つ引数はリストの最後でなければならない
  • 戻り値の型宣言がある場合、コロンと型宣言の間にスペースが必要
  • null許容型宣言では疑問符と型の間にスペースがあってはならない
  • 参照演算子と型の間にスペースが有ってはならない
  • 可変長引数のドット演算子と型の間にスペースがあってはならない
<?php

namespace Vendor\Package;

class ClassName
{
    public function foo(?int $arg1, &$arg2, $arg3 = []): string
    {
        // method body
    }
}
  • 引数リストは複数行に分割でき、後続の各行は一回インデントされる
  • その場合、リストの最初の引数は次の行にある必要がある
<?php

namespace Vendor\Package;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // method body
    }
}
abstract, final, and static
  • abstractおよびfinal宣言がある場合、それらは可視性宣言の前になければならない
  • static宣言がある場合、それらは可視性宣言のあとになければならない
<?php

namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

    final public static function bar()
    {
        // method body
    }
}
Method and Function Calls

メソッドまたは関数を呼び出す場合 - 括弧の前後にスペースがあってはならない - 引数リストの記法については定義するときと同じ

<?php

bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

Control Structures

  • 制御構造キーワードの後にスペースが必要
  • 右括弧と左波括弧の間にスペースが必要
  • 波括弧内の文は一段インデントする
    if, elseif, else
<?php

if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}
switch
<?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;
}
while, do while
<?php

while ($expr) {
    // structure body
}
<?php

do {
    // structure body;
} while ($expr);
for
<?php

for ($i = 0; $i < 10; $i++) {
    // for body
}
foreach
<?php
foreach ($iterable as $key => $value) {
    // foreach body
}
try, catch, finally
<?php

try {
    // try body
} catch (FirstThrowableType $e) {
    // catch body
} catch (OtherThrowableType | AnotherThrowableType $e) {
    // catch body
} finally {
    // finally body
}

Operator

単項演算子
<?php

$i++;

++$j;
二項演算子
<?php
if ($a === $b) {
    $foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
    $foo = $a + $b * $c;
}
三項演算子
  • 「?」文字と「:」文字の両方の前後に少なくとも1つのスペースが必要
<?php
$variable = $foo ? 'foo' : 'bar';

Closures

  • 左波括弧は同じ行に配置する
  • 右波括弧は本文に続く次の行に配置する
  • 引数リスト・変数リストでは各コンマの前にスペースがあってはならず、後にスペースがなければならない
  • デフォルト値を持つ引数はリストの最後に配置する
<?php

$closureWithArgs = function ($arg1, $arg2) {
    // body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // body
};

$closureWithArgsVarsAndReturn = function ($arg1, $arg2) use ($var1, $var2): bool {
    // body
};

クロージャーが関数またはメソッドの呼び出しで引数として直接使用される場合にも、フォーマット規則が適用される。

<?php

$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // body
    },
    $arg3
);