⚒️
PHPStanのbaselineを設定して既存のコードに影響を与えずにdeclare(strict_types=1);を強制する
背景
長くプロジェクトをやっているとPHPがゆるふわ型のまま放置されていることがありますよね。
そんなとき、declare(strict_types=1);を強制するルールを適用したいけど、既存のコード全部にdeclare(strict_types=1);をつけるのは無理だ。。なんてことになると思います。
そこでPHPStanのbaselineを設定することで既存のコードに影響を与えずにdeclare(strict_types=1);を強制することができます。
ちなみにPHPStanの標準ルールではそんなルールがないし追加する気もないっぽい
ので、↓を使っていきます。
やり方
- ergebnis/phpstan-rulesをインストール
composer require --dev ergebnis/phpstan-rules
- phpstan.neonに以下を追加
phpstan.neon
services:
-
class: Ergebnis\PHPStan\Rules\Files\DeclareStrictTypesRule
tags:
- phpstan.rules.rule
このtagsってのがいまいちわかっていないのだが、なんかないと動かなかった。
ergebnis/phpstan-rulesはいろんなルールが入っているので、declare(strict_types=1);を強制するルールだけを適用します。
- baselineを作成
./vendor/bin/phpstan analyze --generate-baseline
- includesされてなければphpstan-baseline.neonをinclude
phpstan.neon
includes:
- phpstan-baseline.neon
- phpstanを動かしてエラーが出ないことを確認
# ./vendor/bin/phpstan analyse
Note: Using configuration file /var/www/phpstan.neon.
1956/1956 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
[OK] No errors
- 敢えて既存のファイルのdeclare_typeを外して、phpstanを動かしてエラーが出るか確認
# ./vendor/bin/phpstan analyse
Note: Using configuration file /var/www/phpstan.neon.
1956/1956 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ ---------------------------------------------------------------------------------------------------
Line sample.php
------ ---------------------------------------------------------------------------------------------------
4 File is missing a "declare(strict_types=1)" declaration.
------ ---------------------------------------------------------------------------------------------------
[ERROR] Found 1 error
注意
baselineはこのファイルにエラーが出るはずというのを記録するファイルなので、既存のdeclare(strict_types=1);がついていないファイルにdeclare(strict_types=1);を追加すると
Ignored error pattern #^File is missing a "declare\(strict_types\=1\)" declaration\.$# in path sample.php was not matched in reported errors.
phpstanが落ちるようになります。
その場合は
./vendor/bin/phpstan analyze --generate-baseline
を再実行してbaselineを再生成してください。
まとめ
やってることは大したことないんですが、意外とこのピンポイントな情報がネットにない気がしたので書いてみました。
LaravelだとPintとかでできそうなんですが、多分PintはbaselineみたいなものがないのでPHPStanでやるかーと思ってこうなりました。
型の力で堅牢なPHPライフを!
Discussion