Points & Lines

PHPStanによる静的解析

PHPStanで静的解析を行う

環境: PHP 7.4.8, PHPStan 1.2.0

静的解析とは

プログラム実行前にソースコードが適切な状態かをチェックすること。

静的解析を行うことで未定義の変数、関数、引数や戻り値の型の不一致など、PHPの文法上は誤りではないが、不具合の原因となる可能性のある箇所を実行前に発見することができる。

PHPのような事前にコンパイルを行わないインタプリタ言語では本記事で紹介するPHPStanなどのツールを用いて静的解析を行う。

※ 文法やコーディング規約チェックにはPHP_CodeSnifferなどのツールを使用する。

PHPStanのインストール

https://phpstan.org/
https://packagist.org/packages/phpstan/phpstan

composerを使用してプロジェクトにインストールする

composer require phpstan/phpstan

または

composer require --dev phpstan/phpstan

(開発環境のみで使用する)

静的解析の実行

下記コマンドで静的解析を実行し、表示される解析結果を確認する

vendor/bin/phpstan analyse --level 0 src/Calculator.php

analyse(解析)サブコマンドは必須。

levelオプション(-lでもOK)で不具合検出ルールのレベルを指定する。

このルールは0から9まで存在しており、数値が大きいほどより厳密なものとなる。
(大きなレベルはそれより小さなレベルのルールも含む)

ルールレベル
https://phpstan.org/user-guide/rule-levels

小さいレベルのルールの方が不具合性が高いものを含むといえるので、まずは0からはじめていき、コードを整えながら徐々にレベルを上げて解析を行うことが推奨されている。

上記の例ではファイルパスまで含めているが、後述の設定ファイルにより解析対象のディレクトリパスごと指定できる。

PHPStanの設定ファイル

静的解析実行時の設定は構成ファイル、phpstan.neonを作成して行う。
https://phpstan.org/config-reference#multiple-files

phpstan.neon (コマンド実行時のパスに作成する)

parameters:
	level: 6
	paths:
		- src
		- tests

上記内容の場合、実行コマンドへオプションとパスの指定なしでsrc配下とtest配下のソースプログラムをルールレベル6で解析実行する。

(実行時にphpstan.neonが自動的に読み込まれる)

vendor/bin/phpstan analyse

特定のエラーメッセージを無視する

静的解析実行で検出されたエラーのうち都合によって修正できないもの、修正を行わなくてよいもの等がある場合、設定ファイルにより検出されないようにできる。

例として解析実行時に下記のエラーメッセージが表示されないようにする。
「app\src\Calculatorクラス内のメソッド、subが未定義」

  15     Call to an undefined method app\src\Calculator::sub().

phpstan.neon内、ignoreErrors項目に無視したいエラーメッセージを追加する。

phpstan.neon

parameters:
    level: 6
    paths:
        - src
        - test
    ignoreErrors:
        - '#Call to an undefined method [a-zA-Z0-9\\_]+::sub\(\)#'

メッセージの記載に正規表現を用いる、特殊文字は\(バックスラッシュ)でエスケープする必要がある。
設定後に解析を際実行するとエラーが検出されないようになる。

現時点からのエラーのみを検出させる(ベースライン機能)

直近に行った実装、改修で発生しているエラーのみを解析して抽出したい場合など、現時点で既出のエラーを全て無視するにはベースラインという機能を使用する。

下記を実行し、既出のエラーをまとめて無視するベースラインファイルをする

vendor/bin/phpstan analyse --generate-baseline

generate-baselineオプションにより、phpstan-baseline.neonが自動的に作成される。

phpstan-baseline.neon
(ignoreErrorsに既出のエラー全てが含まれる)

parameters:
    ignoreErrors:
        -
            message: "#^Call to an undefined method app\\\\src\\\\Calculator\\:\\:sub\\(\\)\\.$#"
            count: 1
            path: src/Calculator.php

        -
            message: "#^example$#"
            count: 1
            path: src/Example.php

        -
            message: "#^example$#"
            count: 1
            path: src/Example.php

このベースラインファイルを下記のように、phpstan.neonから読み込むことで既出のエラーを全て無視できる。
phpstan.neon

includes:
    - phpstan-baseline.neon
parameters:
    level: 6
    paths:
        - src
        - test
ベースラインファイルのエラーが発生していない場合の通知をオフにする

ベースラインファイルに登録された既出のエラー箇所が修正されている場合、ベースラインファイルとソースコードに矛盾があるため、実行時に下記のエラーメッセージが通知される。

Ignored error pattern #^  example~ was not matched in reported errors.

この通知が表示されないようにするにはphpstan.neonで、reportUnmatchedIgnoredErrorsの設定を行う。

phpstan.neon

includes:
    - phpstan-baseline.neon
parameters:
    level: 6
    paths:
        - src
        - test
    reportUnmatchedIgnoredErrors: false

Follow me!

モバイルバージョンを終了