PHP CodeSniffer を試す

# PHP_CodeSnifferとは

コード規約のチェックを行うツール。
v2.Xから修正もできるようになったので試してみる

詳細は[Wiki](https://github.com/squizlabs/PHP_CodeSniffer/wiki)参照。

# インストール

composerのrequire-devに追加すればOK。  

各種フレームワークに対応した規約定義も存在する。
今回は `FuelPHP` のものを使用する。
⇒ `eviweb/fuelphp-phpcs`

```
{
    "require-dev": {
        "squizlabs/php_codesniffer": "2.*",
        "eviweb/fuelphp-phpcs": "dev-master"
    }
}
```

composerで追加インストール

```
$ php composer.phar update squizlabs/php_codesniffer eviweb/fuelphp-phpcs
```

`php_codesniffer` から `fuelphp-phpcs` の設定を参照できるようにする

```
$ fuel/vendor/bin/phpcs --config-set installed_paths fuel/vendor/eviweb/fuelphp-phpcs/Standards
```

`FuelPHP`が追加されていることを確認

```
$ fuel/vendor/bin/phpcs --config-show
installed_paths: /var/www/html/fuel/vendor/eviweb/fuelphp-phpcs/Standards
$ vendor/bin/phpcs -i
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz, Zend and FuelPHP
```


# コード規約チェック

### オプション

* 標準ルール指定

```
$ fuel/vendor/bin/phpcs  --standard=FuelPHP {path}
```

* 拡張子指定

```
$ fuel/vendor/bin/phpcs  --extensions=php {path}
```

チェック実行してみる

```
$ fuel/vendor/bin/phpcs --standard=FuelPHP --extensions=php fuel/app/classes
FILE: /var/www/html/fuel/app/classes/view/welcome/404.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 29 | ERROR | Array with multiple values cannot be declared on a
    |       | single line
----------------------------------------------------------------------

Time: 294ms; Memory: 3.5Mb
```

デフォルトのファイルがひっかかった。。
[Fuelのコード規約](http://fuelphp.jp/docs/1.7/general/coding_standards.html)では、多項目の配列を一行で定義してもOKなのに。。

> $array = array(1, 2, 3, 4);

このチェックを外してみる。

# 独自ルール作成

* xmlでルールを定義する
* 既存のルールを継承して、一部の規約を除外する等の設定が可能
* 全く新規のチェックを実装することも可能
    * 新規ルールの実装方法は[チュートリアル](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Coding-Standard-Tutorial)参照

今回は上記の`FuelPHP`から*Array with multiple values cannot be declared on a single line*というチェックしているルールを除外した独自ルールを作成してみる。

* チェック処理は`fuel/vendor/eviweb/fuelphp-phpcs/Standards/FuelPHP/Sniffs/Arrays/ArrayDeclarationSniff.php`に記述されていた
* 基本的に`$phpcsFile->addError($error, $stackPtr, 'SingleLineNotAllowed')`という感じで、addError()の第３引数にルール名がセットされているようなので、エラーメッセージから除外したいルール名を見つけられる

```shell-session:FuelPHP/Sniffs/Arrays/ArrayDeclarationSniff.php
if (($conditionCheck === false) || ($tokens[$conditionCheck]['line'] !== $tokens[$stackPtr]['line'])) {
    $error = 'Array with multiple values cannot be declared on a single line';
    $phpcsFile->addError($error, $stackPtr, 'SingleLineNotAllowed');
    return;
}
```

```shell-session:ruleset.xml
<?xml version="1.0" encoding="UTF-8"?>

<ruleset name="Fuel_Custom">
    <description>
        Customize Coding standards for FuelPHP
    </description>

    <exclude-pattern>tests/*</exclude-pattern>

    <!-- 継承するルールを指定 -->
    <rule ref="FuelPHP">
        <!-- 除去する個別ルールを指定 -->
    	<exclude name="FuelPHP.Arrays.ArrayDeclaration.SingleLineNotAllowed"/>
    </rule>
</ruleset>
```

作成した`ruleset.xml`を指定してチェック。

```
$ fuel/vendor/bin/phpcs --standard=ruleset.xml --extensions=php fuel/app/classes
```

無事に通った模様。

除外したいルールが１、２個ならコマンド引数で除外したいところだけど、helpを見た限りではできないっぽい。。

# 修正

```
$ fuel/vendor/bin/phpcbf fuel/app/classes
```

* 自動で修正できれば直してくれる
* 上記の`SingleLineNotAllowed`エラーに関しては自動修正してくれなかった。。

---

# 気になった点

* インデントはタブで入力する規則だが、`タブタブ半角SP`のように先頭がタブだと通ってしまう