PSR-12 Extended Coding Style Guide

[PSR一覧](http://qiita.com/rana_kualu/items/f41d8f657df7709bda0f)
[PSR-5](8b2d9d42b81e9f6f0fd1) / [PSR-6](b37c226363f3015951b6) / [PSR-11](a45829de16380af5acd0) / [PSR-12](28f169bb3eadc6f9e3f3) / [PSR-14](aa60378265d802051397) / [PSR-16](f25ab973b975a274b151)


[PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md)は古くなったPSR-2の置き換えです。
端的に言うとPHP7への対応でしょう。
2016/03/29現在まだDraftなので変わる可能性があります。

特に全文和訳する気はないので適当に抜き出してみました。
例によって英語は斜め読みなのであまり信用しないように。

# 1. Overview

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

```php
<?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をグループ化してはいけない。

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

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

```php
<?php declare(strict_types=1); ?>
<html>
  以下略
```

# 4. Classes, Properties, and Methods

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

```php
  if($hoge){
    // 長い行
  } // endif($hoge)
```

みたいな書き方はいけないらしい。
これは実用的にわりと困りそう
ifを長くするんじゃないとか言われてもテンプレート内とかだと難しいんだよね。

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

```php
  new stdClass(); // OK
  new stdClass;   // NG
```

* クラス名定義のextendsとimplementsは1行で書かないといけない。
* implementsは長くなりそうなら改行して書いてよいが、その場合は必ずひとつごとに改行する。
* {}はそれぞれ単独行にする。

```php
class ClassName extends ParentClass implements
    \ArrayAccess,
    \Countable
{
    // 本体
}
```

個人的に{で単独行取るのが好きではない。
特に全部揃ってるならまだマシなんだが、ifとかuseとかは改行しないからなんでだよってなる。

* トレイトは{直後に書かないといけない。ひとつごとに改行する。
* トレイト以外何もない場合はuseの後1行空けずに}で閉じる。
* 他に何かある場合は1行空けて続ける。

```php
class ClassName
{
    use FirstTrait;
    use SecondTrait;
}
```

* プロパティのアクセス修飾子は必ず明記する。varは使用不可。
* アクセス権を示すためにプロパティ名の_を使ってはいけない。
* 意味を持たせずに使うのは問題ないようだ。

```php
class ClassName
{
    public $foo = null;
}
```

* メソッドのアクセス修飾子は必ず明記する。
* アクセス権を示すためにメソッド名の_を使ってはいけない。
* メソッドの{}は単独行で書く。
* 引数の,は、前にはスペース不要、後ろには必要。
* スカラータイプヒンティングは小文字で書く。
* 引数が長くなる場合は改行してよいが、その場合は引数ひとつごとに改行する。その場合のみ引数閉じ括弧と本体始まりを1行で書く。
* 返り値のタイプヒンティングは):はスペース無し、その後はスペースひとつ。
* abstract、finalはアクセス修飾子より先に書く。
* staticはアクセス修飾子より後ろに書く。


```php
    final public function fooBar($arg1): string
    {
        // 関数はアクセス修飾子がないだけで他は同じ
    }
    
    public static function fooBarBaz(
        int $arg1,
        &$arg2,
        $arg3 = []
    ) {
        // 本体
    }
```

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


* メソッドや関数呼び出しは、,の後以外スペースを空けない。
* 引数が長くなる場合は改行してよいが、その場合は引数ひとつごとに改行する。

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

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

# 5. Control Structures

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

# 6. Operators

演算子の項目が増えた。

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

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

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

# 7. Closures

PSR-2と同じ。

# 8. Anonymous Classes

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

```php
$instance = new class extends \Foo implements \HandleableInterface {
    // 本文
};

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

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

# 参考

* PSR-12
https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md

* PSR-2
http://www.infiniteloop.co.jp/docs/psr/psr-2-coding-style-guide.html
http://www.php-fig.org/psr/psr-2/