レガシーなPJにはPHP Insightsをぶち込むのがいいんじゃない？って話

# はじめに

昨今のPHPシステム開発において、静的解析ツールは当然入っている前提で話が進んでいくような気がする。

私の周りでは**既存のコードが汚く、ツールは昔入れたがほとんど何もチェックしてない**、、、みたいな事例が多く観測されている。（これはフィクションです。

一行のエラーを許さない0か100みたいな静的解析じゃなくて、**少しずつ漸進的に**静的解析を導入していきたい、、、

そんな思いを解決する神ツールを発見。

https://phpinsights.com/

ここからはPHPStan等の他ツールと比較しながらPHP Insightsを紹介する。

# 使用方法

## 環境情報

今回はLaravelでの開発を想定する。

```shell
$ php -v
PHP 8.1.12 (cli) (built: Oct 28 2022 18:32:20) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.12, Copyright (c) Zend Technologies

$ php artisan -V
Laravel Framework 9.37.0
```

## 導入手順

今回は以下のコマンドを実行した。

```shell
$ composer require nunomaduro/phpinsights --dev
$ php artisan vendor:publish
$ provider="NunoMaduro\PhpInsights\Application\Adapters\Laravel\InsightsServiceProvider"
```

# 従来の静的解析と比較したPHP Insightsの強み

## スコアでコード品質を計測するため導入が容易

### 従来の静的解析の場合

比較としてPHPStanを実行してみる。

```shell
root@53c6b058d528:/workspace# vendor/bin/phpstan analyze ./app  --level=2
 23/23 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ ------------------------------------------------------------------------------------------------------------- 
  Line   Http/Controllers/GenerateQuestionAction.php                                                                  
 ------ ------------------------------------------------------------------------------------------------------------- 
  29     PHPDoc tag @return with type Illuminate\Http\Response is incompatible with native type App\Models\Question.  
 ------ ------------------------------------------------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------------------------------------------------------ 
  Line   Http/Middleware/Authenticate.php                                                                                  
 ------ ------------------------------------------------------------------------------------------------------------------ 
  17     Method App\Http\Middleware\Authenticate::redirectTo() should return string|null but return statement is missing.  
 ------ ------------------------------------------------------------------------------------------------------------------ 

                                                                                                                        
 [ERROR] Found 2 errors                                                                                                 
                                                                                             
```

このようによろしくないコードを検知してくれるわけだが、エラー検知時にはエラーコードが返りCIは落ちる。

つまり巨大なレガシープロジェクトで静的解析を導入しようとすると、大量のエラーが発生し、CIを通すために大量のコードを修正しなければならない。

そのため**レガシーなプロジェクトでは、開発途中から静的解析を導入するコストが高くつきやすい。**

### PHP Insightsの場合

PHP Insightsを実行すると**スコア形式で**コード品質を計測する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290859/fa422615-9215-f99c-665a-cfc8e934fb1e.png)

また`--min=quality`等でスコアの下限値を設定しない限り、スコアが低くともコマンドは正常終了したとみなされる。

つまりルールに違反した**大量のエラーが存在する状態でも、CIへの導入が容易**と考えられる。

:::note warn
当然ルールに違反するコードはバグや可読性の低下等につながりやすいので、将来的に修正する必要があります。
:::

また先ほど言及した`--min=quality`オプション等で導入時に算出されたスコアを下限値として設定すれば、**コード品質が導入時より下がらないようCIで担保する**こともできる。

## 一つのツールで様々な観点からのコード解析が可能

### 従来の場合

コード品質測定の観点はスタイル、循環複雑度、バグになりやすい書き方、、、等の様々な観点があるが、これらを一つずつ解析しようとすると[PHPStan](https://phpstan.org/)、[PhpMetrics](https://phpmetrics.org/)、[PHP CS Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer)、など複数のツールを使わなければならないことが多い。

またそれぞれの設定ファイルを記述することも、初期導入時はそれなりにコストがかかることになる。

### PHP Insightsの場合

PHP Insightsはこれ一つで循環複雑度、スタイル、バグになりやすい書き方等を一気に解析することが可能。

また設定も一つのファイルに集約されており、導入するだけであれば調整する箇所も少ないためすぐにCIに組み込みやすい。

より厳しい設定を試したい場合は`insights.php`の`remove`パラメータに設定されている規則をコメントアウトしてみると良いだろう。

```php:insights.php
    'remove' => [
        AlphabeticallySortedUsesSniff::class,
        DeclareStrictTypesSniff::class,
        ...
```

さらに設定をカスタマイズしたい場合は公式ドキュメントに方法が書いてあるので参照されたし。

https://phpinsights.com/insights/#exclude-folder-or-files

# まとめ

ここまでPHP Insightsの使用方法や利点について述べた。

もちろんPHP Insightsにも苦手分野はあり、「より厳格なルールセットを迅速に適応したい」などのユースケースでは、PHPStan等のツールを単体で導入したほうが良いと私は考える。

なので静的解析を導入する場合は、解決したい課題やPJの特性に合わせて最適なツールを選定していただき、選択肢の一つとしてPHP Insightsを考えていただければと思う。

以上。

# 宣伝

本記事は以下のイベントに合わせて執筆されたものです。

https://qiita.com/official-events/8e3542610897d988e66d

いいねをください。