php
PHPStanを導入したときのメモを一部修正して共有する。
PHPの静的解析ツール。 0~9段階の強度でPHPコードを解析し、エラーの発見や潜在的なエラー(Warning、非推奨)、型付けの強制などを機械的に行うことが可能。 PHPStan自体が依存パッケージの名前空間を分離していてパッケージ依存がないためアップデートの障壁になる可能性が低い。 また、Dockerを利用した開発環境では開発用のコンテナの中でインストールし動かせばいいため捨てるのも簡単で開発効率の向上のために入れておくと便利です。
PHPを実行するコンテナへ入り、Composerを利用してインストールします。($の後のコマンドが通常のターミナル、コンテナ内で実行するコマンドは#の後に記述します)
$ docker exec -it [PHPが実行できるコンテナ名] bash # cd /var/www/html/ # composer require --dev -W phpstan/phpstan phpstan/extension-installer
*/var/www/htmlがドキュメントルートでこのディレクトリ内にLaravelソースコードが展開されている構成です。
$ docker exec laravel-web_sub /var/www/html/vendor/bin/phpstan analyze /var/www/html/app --memory-limit=256M
/var/www/html/appでLaravelのapp以下のディレクトリの解析を指定します。
CLIオプションで--memory-limit=256M
を指定しています。これはデフォルトだとメモリ不足でエラーが発生するためです。
最低レベル(レベル0)
$ docker exec laravel-web_sub /var/www/html/vendor/bin/phpstan analyze --level 0 ./var/www/html/app --memory-limit=256M
レベルMax(レベル8)
$ docker exec laravel-web_sub /var/www/html/vendor/bin/phpstan analyze --level max ./var/www/html/app --memory-limit=256M
$ docker exec laravel-web_sub /var/www/html/vendor/bin/phpstan analyze /var/www/html/app --memory-limit=256M 77/77 [aaaaaaaaaaaaaaaaaaaaaaaaaaaa] 100% ------ --------------------------------------------------------------------- Line Exceptions/Handler.php ------ --------------------------------------------------------------------- 53 Function respomse not found. ? Learn more at <https://phpstan.org/user-guide/discovering-symbols> ------ --------------------------------------------------------------------- ------ --------------------------------------------------------------------- Line Http/Kernel.php ------ --------------------------------------------------------------------- 62 Class App\\Http\\Middleware\\RedirectIfAuthenticated not found. ? Learn more at <https://phpstan.org/user-guide/discovering-symbols> ------ --------------------------------------------------------------------- ------ ---------------------------------------------------------------- Line Http/Middleware/RedirectIfAuthenticated.php ------ ---------------------------------------------------------------- 24 Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING on line 24 24 Syntax error, unexpected T_STRING, expecting ')' on line 24 27 Syntax error, unexpected T_ENCAPSED_AND_WHITESPACE on line 27 ------ ---------------------------------------------------------------- ------ ------------------------------------------------------------------- Line Library/ItemLib.php ------ ------------------------------------------------------------------- 81 Array has 2 duplicate keys with value 'k_ur_tanka' ('k_ur_tanka', 'k_ur_tanka'). 82 Array has 3 duplicate keys with value 'n_ur_soryo' ('n_ur_soryo', 'n_ur_soryo', 'n_ur_soryo'). ------ ------------------------------------------------------------------- ------ --------------------------------------------------------------------- Line Providers/AppServiceProvider.php ------ --------------------------------------------------------------------- 26 Call to static method startsWith() on an unknown class Str. ? Learn more at <https://phpstan.org/user-guide/discovering-symbols> ------ --------------------------------------------------------------------- [ERROR] Found 8 errors
レベル0で基本的なチェックを行ったところ8件のエラーが検出できました。
$this
で呼び出された未知のメソッド、それらのメソッドや関数に渡される引数の数が間違っている、常に未定義の変数__call
と__get
を利用する未知のマジックメソッドやクラスプロパティの可能性instanceof
およびその他の型チェック、デッドelse
ブランチ、リターン後の到達不能コード。等PHPStanをGithub ActionsやGitlab CIなどでプルリクエスト/マージリクエストの作成時に自動実行させ、特定のレベルのエラーを含むソースコードのマージをリジェクトする方法も他企業で採用されている例があります。 コードレビューや動作確認の手戻りを防ぐためにこちらも検討したい内容だと思います。
開発時に実行しないと発見できないエラーも探すことができ、コードの品質を高めるうえで非常に有用だと感じています。
最近の開発ではAPIによるデータ連携を実装しましたが、API側の実装にFatalエラーがあったことでレスポンスが返ってこなくなり原因の究明に時間がかかって開発体験が感じました。原因はPHPStanのレベル0で検出できるものであの時導入していれば…と思いました。
また、今後も使ってよかったことがあればこのブログで共有できればいいと思います。