【PHP】phpcs の ignore 新構文（CodeSniffer のエラーを特定のメソッドや箇所のみ無効にしたい）

## CodeSniffer から[キャメルクラッチ](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%AF%E3%83%A9%E3%83%83%E3%83%81)をくらう

> PHP, Javascript, CSS のコーディング規約チェッカーである <code>[phpcs](https://github.com/squizlabs/PHP_CodeSniffer/wiki)</code> から<font color=darkorange><strong>叱られるも、やんごとなき事情で変えられない</strong></font>。
>
> 具体的には "`Method name ... is not in camel caps format`"（メソッド名がキャメル・ケースではない）と叱られるのだが、その<font color=darkorange><strong>特定の箇所だけ無視して（チェックしないで）欲しい</strong></font>のである。

```text:PSR-2をstandardに設定して叱られる例
Method name "MySampleClass::my_sample_method" is not in camel caps format
```

[「phpcs エラー 無視 特定のメソッド」で Qiita 記事に絞ってググって](https://www.google.com/search?q=site:qiita.com+phpcs+%E3%82%A8%E3%83%A9%E3%83%BC+%E7%84%A1%E8%A6%96+%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)みても、タイトルからわかりやすい記事がヒットしなかったり、古い記法ばかりだったので自分のググラビリティとして。

## TL; DR <sub><sup>（今北産業）</sup></sub>

> もっとも簡単な方法は<font color=darkorange>**コメントで `// phpcs:ignore` を指定する**</font>。

1. PHP_CodeSniffer（`phpcs`） **v3.2.0 以前と以後で記述方法が異なります**。
2. **v4.0（次期バージョン）からは旧記法は使えなくなります**。
3. PHPDoc 形式（`/** ... */`）では記述できません。`// ...` コメントで記述します。

---

```php:1行のみ無視する
class Foo
{
    // phpcs:ignore
    $foo = [1,2,3];   // 無視される
    bar($foo, false); // チェックされる
}

class Hoge
{
    // 以下の１行は無視される
    $hoge = [1,2,3];    // phpcs:ignore
    fuga($hoge, false); // チェックされる
}

// phpcs:ignore
class hoge_fuga         // 無視される
{
    $hoge = [1,2,3];    // チェックされる
    fuga($hoge, false); // チェックされる
}
```

```php:特定の「チェック項目名」を指定して無視させる
class Foo
{
    // phpcs:ignore PSR1.Methods.CamelCapsMethodName
    $foo = [1,2,3];   // CamelCapsMethodName のチェックだけ無視される
    bar($foo, false); // すべてチェックされる
}
```

```php:--で、メモ（コメント）を付ける
// phpcs:ignore -- 継承元のメソッド名であるため無視
class hoge_fuga         // 無視される
{
    $hoge = [1,2,3];    // チェックされる
    fuga($hoge, false); // チェックされる
}
```

```php:複数行を無視する（ブロック指定）
class Foo             // チェックされる
{
    // phpcs:disable
    $foo = [1,2,3];   // 無視される
    bar($foo, false); // 無視される
    // phpcs:enable
}
```

```php:特定のチェック内容のみ指定ブロックを無視する（以下はTODOコメントの有無を無視する例）
// チェック項目名 "Generic.Commenting.Todo.Found" のみを無効にする

// phpcs:disable Generic.Commenting.Todo.Found
$xmlPackage = new XMLPackage;
$xmlPackage['error_code'] = get_default_error_code_value();
// TODO: エラーメッセージを表示予定が未定で要相談
$xmlPackage->send();
// phpcs:enable // 再有効化
```

```php:複数設定、一部のチェックの有効化後に設定をリセット
// 以下で PEAR のコード規約と Squiz.Arrays の構文チェックを無視する
// phpcs:disable PEAR,Squiz.Arrays
$foo = [1,2,3];
bar($foo,true);

// 以下で PEAR の特定チェックだけ有効にする
// phpcs:enable PEAR.Functions.FunctionCallSignature
bar($foo,false);

// 以下で全ての設定を元に戻す
// phpcs:enable
```

```php:ファイル全体を無視する
<?php
// phpcs:ignoreFile
// 以下はすべて無視される（チェックされない）

class Foo
{
    $foo = [1,2,3];
    bar($foo, false);
}
```

```bash:現在の規約やチェック項目の確認
$ # 以下で無視 or 有効化したい「チェック項目名」を確認できる
$ ./vendor/bin/phpcs -e
```

## TS; DR <sub><sup>（ルールは破るためにあるんだ。だって上流が破ってるんだもの）</sup></sub>

ある PHP クラスを継承（`extends`）した際に、[メソッド（クラス内の関数）をオーバーライドする](https://www.php.net/manual/ja/language.oop5.basic.php#language.oop5.basic.extends)必要がありました。つまり、クラスを継承して特定のメソッドを独自に再実装する必要があったのです。

しかし、そのメソッド名が設定しているコード規約に準拠していないため PHP_CodeSniffer（`phpcs`）から叱られます。この時の規約は `phpcs --standard=PSR2` です。

```text:PSRのstandardをPSR-2に設定した例（PSR-1のメソッド名規約に違反）
----------------------------------------------------------------------
FOUND 8 ERRORS AFFECTING 8 LINES
----------------------------------------------------------------------
 26 | ERROR | Method name "MockPhpStream::buffer_filename" is not in
    |       | camel caps format
 31 | ERROR | Method name "MockPhpStream::stream_open" is not in
    |       | camel caps format
 36 | ERROR | Method name "MockPhpStream::stream_close" is not in
    |       | camel caps format
 40 | ERROR | Method name "MockPhpStream::stream_stat" is not in
    |       | camel caps format
 45 | ERROR | Method name "MockPhpStream::stream_flush" is not in
    |       | camel caps format
 50 | ERROR | Method name "MockPhpStream::stream_read" is not in
    |       | camel caps format
 62 | ERROR | Method name "MockPhpStream::stream_eof" is not in camel
    |       | caps format
 67 | ERROR | Method name "MockPhpStream::stream_write" is not in
    |       | camel caps format
----------------------------------------------------------------------
```

メソッド名を変えてしまうと、継承元のクラスと互換がなくなってしまうため変えられません。

そのため**特定のメソッドのみエラーを無視させたい**のです。しかし、その特定メソッド以外はチェックして欲しいのです。わがままで、すみません。

しかし、[ググってみる](https://www.google.com/search?q=site:qiita.com+phpcs+%E3%82%A8%E3%83%A9%E3%83%BC+%E7%84%A1%E8%A6%96+%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)と `// @codingStandardsIgnoreLine` と書くように案内している記事が大半でした。

```php:1行のみ無視する（古いバージョンの書き方）
class Foo
{
    // @codingStandardsIgnoreLine
    $foo = [1,2,3];   // 無視される
    bar($foo, false); // チェックされる
}
```

ところが、本家のドキュメント調べると **`// @codingStandards*` の記法は現在非推奨**になっており、`// phpcs:ignore` の記法が推奨されていました。

どうやら `// @codingStandardsIgnoreLine` の記法は `phpcs` v3.2.0 より前のもので、`phpcs` v4.0 からは動かなくなるそうです。

> Note: Before PHP_CodeSniffer version 3.2.0, use `// @codingStandardsIgnoreLine` instead of `// phpcs:ignore`.
> The `@codingStandards` syntax is deprecated and will be removed in PHP_CodeSniffer version 4.0.
> <sup>（[Ignoring Parts of a File](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#ignoring-files-and-folders) | Advanced Usage | Wiki | PHP_CodeSniffer @ GitHub）</sup>
>
> 【🐒 筆者訳】
> 注：PHP_CodeSniffer バージョン 3.2.0 より前では `// phpcs:ignore` の代わりに `// @codingStandardsIgnoreLine` を使用してください。
> `@codingStandards` 構文は非推奨になっており、PHP_CodeSniffer のバージョン 4.0 で廃止・削除されます。

つまり、これからは「`// phpcs:ignore` を使え」ということです。

全てのファイルに適用する場合は `phpcs` の設定ファイルで指定するのが正しいのですが、イレギュラーな場合に指定したかったのです。

注意点として、他のツールのように **PHPDoc 形式では記述できません**。ご注意ください ← 俺

```php:PHPDocのコメント構文は動かない
/**
 * @phpcs:ignore
 */
class my_sample_class  // チェックされる （ignore が効かない）
{
    /**
     * phpcs:ignore
     */
    $foo = [1,2,3];   // チェックされる （ignore が効かない）
    bar($foo, false); // チェックされる （ignore が効かない）
}
```

## 参考文献

- [Advanced Usage](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage) | Wiki | PHP_CodeSniffer @ GitHub
- [PHP_CodeSniffer(phpcs) のチェックを一部無効にする](https://qiita.com/inouet/items/690fefa8a20dff886f30) @ Qiita

## 検証・動作確認環境

```shell-session
$ ./vendor/bin/phpcs --version
PHP_CodeSniffer version 3.5.5 (stable) by Squiz (http://www.squiz.net)

$ php --version
PHP 7.1.33 (cli) (built: Jan 26 2020 22:52:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

$ composer --version
Composer version 1.9.3 2020-02-04 12:58:49
```