PhpStormで局所的にお節介な警告を黙らせる

目的は自分用メモなので、それぞれの例が一般的なのかどうかは分かりません。
バージョンは PhpStorm 2017.2 です。


## オーバーライドしたメソッドと基底クラスのメソッドの戻り値の型が異なる時に出る警告がうざい

たとえば基底クラスのメソッドでは ArrayAccess を実装した何かのクラスを返すよう定義していて、そのメソッドをオーバーライドしたクラスでは \Some\Data を返すよう定義している場合。

```php
<?php

/**
 * @param array|\ArrayAccess $attributes
 * @return \Some\Data
 */
public function createData($attributes = array())
{

    //……何かの処理……

    return parent::createData($attributes);
}
```

\Some\Data は ArrayAccess を implement しているため何ら問題ないはずなのですが、PhpStorm先生は以下のように警告してきます。

> "Return value is expected to be '\Some\Data', 'ArrayAccess'"

オーバーライドの使い方を誤っている（Traitを使いなさい？）ということかもしれませんが、PHP 5.3でも動くようにとか、まあ色々な事情がある中で手数を減らすためにこういう手法を使ってるわけで、PHPDocに ``@return \Some\Data|ArrayAccess`` とか書いてお茶を濁したくはない。
そういう時は以下のようにすればOKです。

```php
<?php

/**
 * @param array|\ArrayAccess $attributes
 * @return \Some\Data
 */
public function createData($attributes = array())
{

    //……何かの処理……

    /** @noinspection PhpIncompatibleReturnTypeInspection */
    return parent::createData($attributes);
}
```

あるいは、こうする方法もありますが…。

```php
<?php

/**
 * @param array|\ArrayAccess $attributes
 * @return \Some\Data
 */
public function createData($attributes = array())
{

    //……何かの処理……

    /** @var $data \Some\Data|\ArrayAccess */
    $data = parent::createData($attributes);
    return $data;
}
```

警告除けのためにソースコードに手を入れること自体が屈辱的ではありますが、こうするよりは行コメントだけで済ませる方がまだマシだと思った次第です。


## 定型的に受け取っているメソッドの引数をメソッド内で使わない時に出る警告がうざい

アプリケーションをトランザクションスクリプト的に構成している場合、何かしらの引数を受けて何かしらの結果を返すようなクラスをたくさん作ることって、ありませんか。

```php
<?php

/**
 * @param \Some\Context $context
 * @return \Some\Result
 */
public function execute(\Some\Context $context)
{

    //……何かの処理……

    return $result;
}
```

こういうやつですが、時々他と違う処理を行うクラスがあって、\Some\Context を使わない場合があります。
でも、PhpStorm先生はそんな設計を許してくれません。

> "Unused parameter 'context'. The value of the parameter is not used anywhere.

こういう時はそのパターンを見出して別途インタフェースを定義して \Some\Context を使わないメソッドを定義して、実装するのが正しいのかもしれませんが、それもちょっとしんどい…。
そういう時は以下のようにすればOKです。

```php
<?php

/**
 * @param \Some\Context $context
 * @return \Some\Result
 */
public function execute(
    /** @noinspection PhpUnusedParameterInspection */
    \Some\Context $context
)
{

    //……何かの処理……

    return $result;
}
```

一行コメントといえばそうですが、改行位置まで変わってしまって、とても苦しい感じです。でも、全ての場面でこの警告を出さないようにするのも危ういので、しょうがない…。


## その他よくある ``@noinspection`` の例

他にも自分の場合は以下のようなケースで ``@noinspection`` を使っています。

- マジックメソッド __get() による動的な（利用側で生やせる）プロパティがある場合…… PhpUndefinedFieldInspection
- マジックメソッド __call() による動的な（利用側で生やせる）メソッドがある場合…… PhpUndefinedMethodInspection
- include() で動的にパスを生成している場合…… PhpIncludeInspection
- list() などで利用しないローカル変数を書かざるを得ない場合…… PhpUnusedLocalVariableInspection
- やむなくエラー制御演算子を利用する場合…… PhpUsageOfSilenceOperatorInspection
- 共有ライブラリのコードのため、現在のメイン環境では deprecate にされている関数を利用せざるを得ない場合…… PhpDeprecationInspection
- \InvalidArgumentException をスローさせるメソッドのテストケース等で故意に不正な引数を与える場合…… PhpParamsInspection


## 文字列リテラルに含まれるHTML/SQLっぽい(HTML/SQLではない）部分で出る警告がうざい

正規表現を使う際、コードの可読性のためにパターン文字列のリテラルで名前付きキャプチャを使うことがあると思いますが、PhpStorm先生はこれをHTMLと誤検知してプリプリ怒ってきます。大変うざい！

![PhpStorm "Element path doesn't have required attribute"](https://cdn-ak2.f.st-hatena.com/images/fotolife/k/k-holy/20171129/20171129121042.png)

設定ウィンドウから Editor → Language Injections で一覧が出てくるので、不要なやつを解除します。

![PhpStorm Settings - Editor > Language Injections](https://cdn-ak2.f.st-hatena.com/images/fotolife/k/k-holy/20171129/20171129121041.png)

これを見たところ、ヒアドキュメント構文のラベルに「SQL」「HTML」「REGEXP」といった特定のキーワードがある場合も、同様に反応して構文チェックを実施するようです。

こういうのこそ ``@noinspection`` で解除させて欲しいところですが、下記のやり取りを読む限りでは、どうも該当するものが無いみたいです。

- [@noinspection for one line &ndash; IDEs Support (IntelliJ Platform) | JetBrains](https://intellij-support.jetbrains.com/hc/en-us/community/posts/207058215--noinspection-for-one-line)


## おまけ：コードインスペクション設定 - PHP編

自分の場合、プロジェクト共通で以下のように設定しています。

設定ウィンドウから Editor → Inspections → PHP

- Code Smell → Case mismatch in method call or class usage にチェックを追加
- Code Smell → Usage of a silence operator にチェックを追加

- Code Style → Unnecessary fully qualified name のチェックを解除

- Probable bugs → Division by zero にチェックを追加
- Probable bugs → Missing paranet call for constructor のチェックを解除

- Undefined → Undefined class → "Don't inspet PHPDoc" にチェックを追加
- Undefined → Undefined field → "Notify about access to a field via magic method" のチェックを解除

- Unused → Unused private field のチェックを解除
- Unused → Unused private method のチェックを解除

UndefinedやUnused辺りはミスを見逃す恐れもあるので良し悪しですが、マジックメソッドによる透過的なプロパティ参照やメソッド呼び出しを頻繁に行っているコードでは局所的な対応が困難なため、やむなく解除しています。

マジックメソッド関連でよく出る警告は、本当に厄介ですね…。


## 参考記事

- [PhpStormで下線警告（インスペクション表示）を出さないようにする - Qiita](http://qiita.com/stk2k/items/1031ea087f23246db700)
- [PHPStorm で @noinspection を広範囲に適用する - Qiita](http://qiita.com/ngyuki/items/2db629ad382c08ff3df2)

下記のGistにはキーワードのリストがありますが、PhpIncompatibleReturnTypeInspection などは含まれていないので、最新版ではないようです。

- [options for phpStorm @noinspection annotation](https://gist.github.com/discordier/ed4b9cba14652e7212f5)

下記のリストは警告メッセージと対で書かれていて、分かりやすいです。

- [PhpStorm @noinspection: bei Sebastian Fischer auf evoWe](https://www.evoweb.de/allgemeine-entwicklung/tools/phpstorm-noinspection.html)

公式のリストってないんでしょうか…。