Edited at

PSR-12 Extended Coding Style Guide

More than 1 year has passed since last update.

PSR一覧

PSR-5 / PSR-6 / PSR-11 / PSR-12 / PSR-14 / PSR-16

PSR-12は古くなったPSR-2の置き換えです。

端的に言うとPHP7への対応でしょう。

2016/03/29現在まだDraftなので変わる可能性があります。

特に全文和訳する気はないので適当に抜き出してみました。

例によって英語は斜め読みなのであまり信用しないように。


1. Overview


  • PSR-12はPSR-2の延長で拡張で置き換えだぜ。

<?php

declare(strict_types=1);

namespace Vendor\Package;

use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\Namespace\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()
{
// method body
}
}

例示は基本的にPSR-12からのコピペです。


2. General

2.5 Keywords and Types以外はPSR-2と同じ。

禁止ワードがtrue, false, nullからarray, int, true, object, float, false, mixed, bool, null, numeric, string, void, resourceに増えた。


3. Declare Statements, Namespace, and Use Declarations


  • decrareについて、strict_typesがある場合は<?phpの次の行に書く、decrareはそれぞれ改行する、decrareの後は1行空ける。


  • useはグループ化できるならグループ化する、前後に1行空ける、。

    useの順番はclass、function、constの順。

    2段階以上異なるnamespaceをグループ化してはいけない。


use A\B{ C\D,   F } // これはOK

use A\B{ C\D\E, F } // こっちはNG



  • 1行目の<?phpの行にはそれ以外を書いてはいけない。
    ただしテンプレートファイルなどでstrict_typesしたい場合は、以下のように1行目に開始タグ、strict_typeの宣言、終了タグを書かなければならない。

<?php declare(strict_types=1); ?>

<html>
以下略


4. Classes, Properties, and Methods


  • 閉じ中括弧にコメントを書いてはいけない。

  if($hoge){

// 長い行
} // endif($hoge)

みたいな書き方はいけないらしい。

これは実用的にわりと困りそう

ifを長くするんじゃないとか言われてもテンプレート内とかだと難しいんだよね。


  • クラスをnewするときに()を略してはいけない。

  new stdClass(); // OK

new stdClass; // NG


  • クラス名定義のextendsとimplementsは1行で書かないといけない。

  • implementsは長くなりそうなら改行して書いてよいが、その場合は必ずひとつごとに改行する。

  • {}はそれぞれ単独行にする。

class ClassName extends ParentClass implements

\ArrayAccess,
\Countable
{
// 本体
}

個人的に{で単独行取るのが好きではない。

特に全部揃ってるならまだマシなんだが、ifとかuseとかは改行しないからなんでだよってなる。


  • トレイトは{直後に書かないといけない。ひとつごとに改行する。

  • トレイト以外何もない場合はuseの後1行空けずに}で閉じる。

  • 他に何かある場合は1行空けて続ける。

class ClassName

{
use FirstTrait;
use SecondTrait;
}


  • プロパティのアクセス修飾子は必ず明記する。varは使用不可。

  • アクセス権を示すためにプロパティ名の_を使ってはいけない。

  • 意味を持たせずに使うのは問題ないようだ。

class ClassName

{
public $foo = null;
}


  • メソッドのアクセス修飾子は必ず明記する。

  • アクセス権を示すためにメソッド名の_を使ってはいけない。

  • メソッドの{}は単独行で書く。

  • 引数の,は、前にはスペース不要、後ろには必要。

  • スカラータイプヒンティングは小文字で書く。

  • 引数が長くなる場合は改行してよいが、その場合は引数ひとつごとに改行する。その場合のみ引数閉じ括弧と本体始まりを1行で書く。

  • 返り値のタイプヒンティングは):はスペース無し、その後はスペースひとつ。

  • abstract、finalはアクセス修飾子より先に書く。

  • staticはアクセス修飾子より後ろに書く。

    final public function fooBar($arg1): string

{
// 関数はアクセス修飾子がないだけで他は同じ
}

public static function fooBarBaz(
int $arg1,
&$arg2,
$arg3 = []
) {
// 本体
}

引数改行しつつの返り値タイプヒンティングは ): string { でいいんじゃろか。


  • メソッドや関数呼び出しは、,の後以外スペースを空けない。

  • 引数が長くなる場合は改行してよいが、その場合は引数ひとつごとに改行する。

bar();

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

somefunction($foo, $bar, [
$hoge,
$fuga
], $baz);


5. Control Structures

finallyが増えたくらいで、他はPSR-2と全く同じ。


6. Operators

演算子の項目が増えた。


  • !以外の代数/比較/代入/ビット/論理/文字列/型演算子は前後にスペースが必要。

  • それ以外は未定。

if ($a === $b) {

$foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
$variable = $foo ? 'foo' : 'bar';
}

~や++みたいな単項演算子はスペース不要でいいと思うのだがどうか。


7. Closures

PSR-2と同じ。


8. Anonymous Classes


  • 無名クラスはクロージャと同じルールに従う。

$instance = new class extends \Foo implements \HandleableInterface {

// 本文
};

// Parenthesis on the next line
$instance = new class extends \Foo implements
\ArrayAccess,
\Countable,
\Serializable
{
// 本文
};

クラスは{を改行しないといけなかったのに、こっちはくっつけていいとか一貫してないよなあ。


参考