【PHPフレームワークFLow】FlowのプロジェクトにPHP Stan入れてみる

# 初めに
Flowのキャッチアップのために記事を書き始めて3か月ほど経ちました。
初めてのPHPにも慣れ、そろそろ静的解析ツールを入れてソースを綺麗にしたいなぁと思っていたので、PHPでよく使われているPHP Stanなるものを入れてみました。

# PHP Stanとは
PHP StanとはPHPのソースで使用される静的解析ツールの一つです。

https://phpstan.org/

以下のようなコードを検出してくれます。

* 型安全性の問題
* 未定義の変数
* 死んだコード（使用されていないコード）
* クラスやメソッドの存在しない呼び出し
* 引数の数や型の不一致
* ...and more!!

## 特徴1：チェックの厳しさを決めることができる
PHP Stanはチェックのレベルを0～9の10段階で設定することができます。
プロジェクトに合わせたレベルを設定できるため、新規導入しやすいのが良いですね。
各レベルの詳細は[こちら](https://phpstan.org/user-guide/rule-levels)をご参照ください。

## 特徴2：特定のFWに特化した拡張機能
LaravelやCakePHPなど、主要なフレームワークやライブラリの検査に特化した拡張機能が存在します。
最初から用意してくれてるので、各々で実施する細かい調整が少なくなりますね。
（当然Flowの拡張機能は存在しないわけですが、、、）


# 導入手順
ということで、実際にFlowのプロジェクトにPHP Stanを導入してみましょう。

## 環境

## 1. composerでPHP Stanをインストール
プロジェクト直下で以下のコマンドを実行し、PHP Stanをインストールします。

```sh
$ composer require --dev phpstan/phpstan
```

 実行後、プロジェクト直下の```bin```ディレクトリにphpstanの実行ファイルが入っていればOKです。

:::note warn
様々な記事で```vendor/bin```に実行ファイルが作成されると書いてありますが、Flowのデフォルト設定だとプロジェクト直下の```bin```に作成されます。
composer.jsonの```config -> bin-dir```の値で指定されているためです。
:::


## 2. phpstan実行してみる
早速実行してみましょう。

自分が今まで書いてきたコードをPHPStanで解析してみます。

```sh
./bin/phpstan analyse Packages/Application/ -l 1
```

| 引数・オプション                          | 説明                                           |
|---------------------------------|--------------------------------------------------------|
| `Packages/Application/`           | 実行するディレクトリ                                   |
| `-l 1`                      | PHP Stanを実行する際のレベルを指定                   |


実際に実行した結果がこちら。
レベル1ですら12個NGがありますね、、、、笑
```sh
$ ./bin/phpstan analyse Packages/Application/ -l 1
 28/28 [============================] 100%

 ------ ---------------------------------------------------------------------
  Line   Neos.Welcome\Classes\Controller\StandardController.php
 ------ ---------------------------------------------------------------------
  42     Constant FLOW_PATH_ROOT not found.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  43     Constant FLOW_PATH_WEB not found.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
 ------ ---------------------------------------------------------------------

 ------ -----------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Classes\View\DownloadView.php
 ------ -----------------------------------------------------------------------------------------------------
  26     Method Neos\Welcome\View\DownloadView::render() should return object|string but return statement is
         missing.
 ------ -----------------------------------------------------------------------------------------------------

 ------ ----------------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Tests\Unit\Domain\Model\Item2Test.php
 ------ ----------------------------------------------------------------------------------------------------------
  11     Class Neos\Welcome\Tests\Unit\Domain\Model\Item2Test extends unknown class Neos\Flow\Tests\UnitTestCase.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  19     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\Item2Test::markTestIncomplete().
  23     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\Item2Test::assertSame().
 ------ ----------------------------------------------------------------------------------------------------------

 ------ ---------------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Tests\Unit\Domain\Model\ItemTest.php
 ------ ---------------------------------------------------------------------------------------------------------
  11     Class Neos\Welcome\Tests\Unit\Domain\Model\ItemTest extends unknown class Neos\Flow\Tests\UnitTestCase.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  19     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\ItemTest::markTestIncomplete().
  23     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\ItemTest::assertSame().
 ------ ---------------------------------------------------------------------------------------------------------

 ------ ----------------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Tests\Unit\Domain\Model\OrderTest.php
 ------ ----------------------------------------------------------------------------------------------------------
  11     Class Neos\Welcome\Tests\Unit\Domain\Model\OrderTest extends unknown class Neos\Flow\Tests\UnitTestCase.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  19     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\OrderTest::markTestIncomplete().
  23     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\OrderTest::assertSame().
 ------ ----------------------------------------------------------------------------------------------------------


 [ERROR] Found 12 errors

```


## ```phpstan.neon```ファイルの作成
`phpstan.neon`はPHP Stanの設定ファイルです。neonという拡張子でyamlファイルと似たいような文法で設定を記載していきます。

プロジェクト直下にファイルを作成し、先ほど実行したコマンドと同等の設定を記載してみました。
```yaml
parameters:
    level: 1
    paths:
        - Packages/Application/
```

実行してみたところ、実行後すぐに```phpstan.neon```が読み込まれていることがわかります。

```sh
> ./bin/phpstan analyse
Note: Using configuration file c:\path\to\project\Quickstart\phpstan.neon.
 28/28 [============================] 100%

 ------ ---------------------------------------------------------------------
  Line   Neos.Welcome\Classes\Controller\StandardController.php
 ------ ---------------------------------------------------------------------
  42     Constant FLOW_PATH_ROOT not found.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  43     Constant FLOW_PATH_WEB not found.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
 ------ ---------------------------------------------------------------------

 ------ -----------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Classes\View\DownloadView.php
 ------ -----------------------------------------------------------------------------------------------------
  26     Method Neos\Welcome\View\DownloadView::render() should return object|string but return statement is
         missing.
 ------ -----------------------------------------------------------------------------------------------------

 ------ ----------------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Tests\Unit\Domain\Model\Item2Test.php
 ------ ----------------------------------------------------------------------------------------------------------
  11     Class Neos\Welcome\Tests\Unit\Domain\Model\Item2Test extends unknown class Neos\Flow\Tests\UnitTestCase.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  19     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\Item2Test::markTestIncomplete().
  23     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\Item2Test::assertSame().
 ------ ----------------------------------------------------------------------------------------------------------

 ------ ---------------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Tests\Unit\Domain\Model\ItemTest.php
 ------ ---------------------------------------------------------------------------------------------------------
  11     Class Neos\Welcome\Tests\Unit\Domain\Model\ItemTest extends unknown class Neos\Flow\Tests\UnitTestCase.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  19     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\ItemTest::markTestIncomplete().
  23     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\ItemTest::assertSame().
 ------ ---------------------------------------------------------------------------------------------------------

 ------ ----------------------------------------------------------------------------------------------------------
  Line   Neos.Welcome\Tests\Unit\Domain\Model\OrderTest.php
 ------ ----------------------------------------------------------------------------------------------------------
  11     Class Neos\Welcome\Tests\Unit\Domain\Model\OrderTest extends unknown class Neos\Flow\Tests\UnitTestCase.
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols
  19     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\OrderTest::markTestIncomplete().
  23     Call to an undefined method Neos\Welcome\Tests\Unit\Domain\Model\OrderTest::assertSame().
 ------ ----------------------------------------------------------------------------------------------------------


 [ERROR] Found 12 errors


```


# 終わりに
一癖ありましたが、問題なく動いてくれてよかったです。
本当はdoctrineの拡張機能まで入れたかったんですが、現在進行形でハマってるので今度別記事にて出す予定です。
読んでいただきありがとうございました！