VSCodeでPHPStanを利用する方法について

採用はこちら

PHPStanは、PHPコードを実行する前に問題を検出できる静的解析ツールです。

型の不一致や存在しないメソッドの呼び出し、戻り値の間違いなどを検出できるため、PHP開発の品質向上に役立ちます。

VSCodeと組み合わせれば、ターミナルからPHPStanを実行するだけでなく、解析結果をエディタ上で確認することもできます。

ここでは、PHPStanのインストールから基本設定、VSCodeとの連携方法、DockerやLaravelで利用する場合のポイントまで詳しく解説します。

目次

PHPStanとは

PHPStanは、PHP向けの静的解析ツールです。

プログラムを実際に動かさなくても、コードを解析して問題を発見できます。

たとえば、次のコードを考えてみましょう。

<?php

function getName(): string
{
    return 123;
}

getName()の戻り値にはstringが指定されています。

しかし、実際には整数の123を返しています。

PHPStanを利用すると、このような型の不一致をコード実行前に検出できます。

PHPStanで検出できる主な問題

PHPStanでは、主に次のような問題を検出できます。

  • 戻り値の型の不一致
  • 引数の型の不一致
  • 存在しないメソッドの呼び出し
  • 存在しないプロパティへのアクセス
  • 引数の数の間違い
  • PHPDocとコードの不整合
  • 配列要素の型の問題
  • 到達不能なコード
  • 常に成立する条件や常に成立しない条件
  • ジェネリクスに関する型の問題

PHPの型宣言やPHPDocが充実しているほど、PHPStanはより詳しい解析を行いやすくなります。

PHPStanを利用するための準備

PHPStanを導入する前に、PHPとComposerが利用できることを確認します。

PHPが利用できるか確認する

VSCodeでターミナルを開き、次のコマンドを実行します。

php -v

PHPのバージョン情報が表示されれば問題ありません。

現在のPHPStanを実行するには、PHP 7.4以上の環境が必要です。

ただし、PHPStanを実行するPHPバージョンと、解析対象プロジェクトが想定しているPHPバージョンは必ずしも同じである必要はありません。

解析対象のPHPバージョンは、PHPStanの設定で指定することもできます。

Composerが利用できるか確認する

続いて、Composerが利用できるか確認します。

composer --version

Composerのバージョン情報が表示されれば利用できます。

PHPStanはPHAR形式でも利用できますが、通常のPHPプロジェクトではComposer経由でインストールする方法が扱いやすいでしょう。

PHPStanをComposerでインストールする

PHPプロジェクトをVSCodeで開く

たとえば、次のようなPHPプロジェクトがあるとします。

my-project/
├─ src/
│  ├─ User.php
│  └─ Product.php
├─ tests/
├─ composer.json
└─ index.php

VSCodeではPHPファイル単体ではなく、基本的にプロジェクトルートのmy-projectを開きます。

PHPStanをインストールする

プロジェクトルートのターミナルで、次のコマンドを実行します。

composer require --dev phpstan/phpstan

--devを付けることで、PHPStanが開発用パッケージとしてrequire-devに追加されます。

composer.jsonには、PHPStanが開発用依存関係として追加されます。

実際に追加されるバージョン番号は、インストール時期やプロジェクトの依存関係によって異なります。

PHPStanがインストールされたか確認する

ComposerでPHPStanをインストールすると、通常は次の場所から実行できます。

vendor/bin/phpstan

macOSやLinux、Git Bashなどでは、次のように確認できます。

vendor/bin/phpstan --version

WindowsのPowerShellやコマンドプロンプトでは、次の形式を利用できます。

.\vendor\bin\phpstan.bat --version

PHPStanのバージョンが表示されれば、インストールは完了です。

PHPStanでコードを解析する

srcディレクトリを解析する

srcディレクトリを解析する場合は、次のコマンドを実行します。

vendor/bin/phpstan analyse src

Windowsでは、次の形式でも実行できます。

.\vendor\bin\phpstan.bat analyse src

PHPStanでは、analyseコマンドを使ってコードを解析します。

複数のディレクトリを解析する

srcとtestsの両方を解析したい場合は、次のように指定できます。

vendor/bin/phpstan analyse src tests

通常は、自分たちで管理しているコードを解析対象にします。

vendorディレクトリ内のライブラリまで解析対象に含める必要はありません。

PHPStanの解析レベルを指定する

PHPStanでは、解析の厳しさをレベルで指定できます。

レベル0〜10を利用する

現在のPHPStanでは、レベル0から10まで用意されています。

数字が大きくなるほど解析が厳しくなります。

たとえば、レベル5で解析する場合は次のようにします。

vendor/bin/phpstan analyse src --level=5

短縮形も利用できます。

vendor/bin/phpstan analyse src -l 5

レベル0は比較的緩く、レベル10が最も厳しい設定です。

level maxを利用する

PHPStanでは、最高レベルを指定するためにmaxを利用することもできます。

vendor/bin/phpstan analyse src --level=max

設定ファイルでは、次のように指定します。

parameters:
    level: max

maxを使用すると、PHPStanの将来のバージョンで解析レベルが追加された場合にも、最高レベルを利用できます。

既存プロジェクトでは段階的にレベルを上げる

既存プロジェクトへPHPStanを導入すると、大量のエラーが表示される場合があります。

そのため、最初からレベル10やmaxを設定する必要はありません。

現在のコードベースで対応可能なレベルから開始し、問題を修正しながら段階的にレベルを上げる方法が現実的です。

たとえば、レベル5から始める方法もありますが、レベル5がPHPStan公式の固定推奨値というわけではありません。

新規プロジェクトであれば、最初から高い解析レベルを設定することも検討できます。

phpstan.neonで設定を管理する

毎回コマンドラインで解析対象やレベルを指定するのは手間がかかります。

そのため、通常はPHPStanの設定ファイルを作成します。

phpstan.neonを作成する

プロジェクトルートに、次のファイルを作成します。

phpstan.neon

たとえば、次のように設定できます。

parameters:
    level: 8

    paths:
        - src
        - tests

この設定では、srcとtestsをレベル8で解析します。

設定後は、次のコマンドだけで解析できます。

vendor/bin/phpstan analyse

PHPStanが自動認識する設定ファイル

PHPStanは、カレントディレクトリから主に次の設定ファイルを探します。

phpstan.neon
phpstan.neon.dist
phpstan.dist.neon

一般的には、phpstan.neonまたはphpstan.neon.distを利用するケースが多いでしょう。

設定ファイルを明示的に指定する

設定ファイルを別の場所に配置する場合は、-cオプションで指定できます。

vendor/bin/phpstan analyse -c config/phpstan.neon

-cは--configurationの短縮形です。

解析対象のPHPバージョンを指定する

PHPStanを実行しているPHPバージョンとは別に、解析対象コードが想定するPHPバージョンを設定できます。

たとえば、PHP 8.4を対象として解析する場合は、次のように設定できます。

parameters:
    phpVersion: 80400

これにより、PHPStanは指定したPHPバージョンを前提として解析します。

開発環境、CI環境、本番環境でPHPバージョンが異なる場合にも役立ちます。

VSCodeでPHPStanを利用する

PHPStan本体はVSCodeの機能ではありません。

基本的には、次の構成で利用します。

PHPStan本体
+
VSCode拡張機能

PHPStan本体はComposerでプロジェクトへインストールし、必要に応じてVSCode用の拡張機能を追加します。

PHPStan用のVSCode拡張機能を利用する

VSCodeで、次のショートカットを押します。

Ctrl + Shift + X

拡張機能の検索画面が開くので、PHPStanと検索します。

PHPStanに対応したVSCode拡張機能はいくつか存在します。

代表的な例として、次のような拡張機能があります。

SanderRonde.phpstan-vscode
swordev.phpstan

これらを利用すると、PHPStanの解析結果をVSCodeのエディタや「問題」パネルへ表示できます。

ただし、これらはPHPStan本体とは別のサードパーティー製拡張機能です。

PHPStan公式の必須拡張機能というわけではありません。

インストール前に、公開者、更新状況、設定方法などを確認するとよいでしょう。

VSCodeの問題パネルでエラーを確認する

PHPStan用の拡張機能を設定すると、解析結果をVSCode上で確認できます。

たとえば、次のコードを考えてみましょう。

<?php

function getPrice(): int
{
    return '1000';
}

戻り値にはintが指定されていますが、実際には文字列を返しています。

PHPStanがこの問題を検出すると、対応するVSCode拡張機能を通じてエディタや「問題」パネルに表示できます。

VSCodeの問題パネルは、次のショートカットで開けます。

Ctrl + Shift + M

VSCodeのsettings.jsonでPHPStanを設定する

利用するVSCode拡張機能によっては、.vscode/settings.jsonからPHPStanの設定を指定できます。

phpstan.binPathを設定する

たとえばSanderRonde.phpstan-vscodeでは、通常、次のPHPStanが利用されます。

${workspaceFolder}/vendor/bin/phpstan

そのため、一般的なComposerプロジェクトであれば、phpstan.binPathを明示的に設定する必要はありません。

独自の場所にPHPStanを配置している場合などに設定します。

{
    "phpstan.binPath": "${workspaceFolder}/vendor/bin/phpstan"
}

phpstan.neonを指定する

設定ファイルを明示的に指定したい場合は、利用する拡張機能に応じて設定できます。

たとえば、次のような形式です。

{
    "phpstan.configFile": "phpstan.neon"
}

ただし、設定項目の名称や仕様はVSCode拡張機能によって異なります。

利用している拡張機能のドキュメントを確認してください。

VSCodeのTasksからPHPStanを実行する

PHPStan用のVSCode拡張機能を導入せず、VSCodeのTasks機能からPHPStanを実行する方法もあります。

tasks.jsonを作成する

.vscode/tasks.jsonを作成し、次のように設定します。

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "PHPStan",
            "type": "shell",
            "command": "vendor/bin/phpstan",
            "args": [
                "analyse"
            ],
            "group": "test",
            "problemMatcher": []
        }
    ]
}

その後、コマンドパレットを開きます。

Ctrl + Shift + P

Tasks: Run Taskを選択し、PHPStanを実行できます。

Windowsの場合は、利用しているシェルによって次のような指定が必要になることがあります。

"command": "vendor\\bin\\phpstan.bat"

Composer ScriptsからPHPStanを実行する

チーム開発では、Composer ScriptsへPHPStanを登録しておくと便利です。

composer.jsonへスクリプトを追加する

たとえば、次のように設定します。

{
    "scripts": {
        "phpstan": "phpstan analyse"
    }
}

すると、次のコマンドでPHPStanを実行できます。

composer phpstan

開発者ごとに異なるコマンドを使わずに済むため、ローカル環境とCIで実行方法を統一しやすくなります。

PHPStanでよく検出されるエラー

戻り値の型が異なる

次のコードでは、戻り値にintが指定されています。

function getAge(): int
{
    return '20';
}

しかし、実際には文字列を返しています。

次のように修正できます。

function getAge(): int
{
    return 20;
}

引数の型が異なる

次のコードでは、double()の引数にintが要求されています。

function double(int $number): int
{
    return $number * 2;
}

double('10');

文字列の'10'を渡しているため、PHPStanで型の問題を検出できます。

存在しないメソッドを呼び出している

次のコードを見てみましょう。

class User
{
    public function getName(): string
    {
        return 'Taro';
    }
}

$user = new User();

$user->getEmail();

UserクラスにはgetEmail()メソッドがありません。

PHPStanを利用すると、このような存在しないメソッドの呼び出しも検出できます。

PHPDocを利用して解析精度を高める

PHPStanはPHPDocの型情報も解析に利用できます。

配列の要素型を指定する

次のコードだけでは、配列に何が入っているのか十分に判断できない場合があります。

function getUsers(): array
{
    return [];
}

そこで、PHPDocを追加します。

/**
 * @return array<int, User>
 */
function getUsers(): array
{
    return [];
}

これによりPHPStanは、配列のキーがint、値がUserであることを認識できます。

適切な型宣言やPHPDocを記述すると、PHPStanの解析精度を高められます。

PHPStanのbaselineを利用する

既存の大規模プロジェクトへPHPStanを導入すると、すぐには修正できない既存エラーが大量に表示される場合があります。

そのような場合に利用できるのがbaselineです。

baselineを生成する

次のコマンドを実行します。

vendor/bin/phpstan analyse --generate-baseline

通常は、次のファイルが生成されます。

phpstan-baseline.neon

baselineをphpstan.neonから読み込む

生成したbaselineは、通常、メインの設定ファイルから読み込みます。

includes:
    - phpstan-baseline.neon

parameters:
    level: 8

    paths:
        - src

これにより、既存の問題をbaselineとして扱いながら、新しく発生した問題を検出しやすくなります。

ただし、baselineはエラーそのものを修正する機能ではありません。

既存コードの問題を一時的に許容し、段階的に改善していくための仕組みとして利用します。

大量のエラーをすべてbaselineへ登録するだけではなく、解析レベルや対象範囲、型情報などもあわせて見直すことが重要です。

Docker環境でPHPStanを利用する

PHPをDockerコンテナ内で実行している場合は、PHPStanもコンテナ内で動かすケースがあります。

Docker Compose経由で実行する

たとえば、PHPコンテナ名がphpの場合は次のように実行できます。

docker compose exec php vendor/bin/phpstan analyse

実際のサービス名や作業ディレクトリは、Docker Composeの設定によって異なります。

VSCode拡張機能からDocker内のPHPStanを実行する

VSCode拡張機能によっては、PHPStanを実行するコマンドを変更できます。

たとえば、SanderRonde.phpstan-vscodeではphpstan.binCommandを利用できます。

また、ホスト側とコンテナ側でパスが異なる場合には、パスの対応設定が必要になるケースがあります。

Docker環境では、次の2点を意識するとトラブルを減らせます。

PHPStanがどこで動作しているか
VSCodeがどのPHPStanを呼び出しているか

LaravelでPHPStanを利用する

Laravelでは、通常のPHPStanだけではフレームワーク固有の仕組みを十分に解析できない場合があります。

そのため、Laravel向けのPHPStan拡張であるLarastanがよく利用されます。

Larastanをインストールする

現在のパッケージ名は次のとおりです。

composer require --dev larastan/larastan

古い記事では、以前のパッケージ名であるnunomaduro/larastanが紹介されていることがあります。

現在はlarastan/larastanを確認するのが適切です。

Larastanの対応PHPバージョンやLaravelバージョンは、Larastanのバージョンによって異なります。

利用中のLaravelに対応するバージョンを確認してから導入してください。

LarastanはLaravelを起動する点に注意する

一般的なPHPStanは静的解析ツールとして利用できます。

一方、LarastanはLaravel固有の型情報を取得するため、LaravelのApplication Containerを起動して解析します。

そのため、Laravel環境では通常のPHPStanとは動作の仕組みが少し異なる点も理解しておくとよいでしょう。

PHPStanが動かない場合の確認ポイント

vendorディレクトリが存在しない

Gitからプロジェクトを取得した直後などでは、vendorディレクトリが存在しない場合があります。

その場合は次のコマンドを実行します。

composer install

phpstanコマンドが見つからない

PHPStanをComposerでプロジェクトへインストールした場合、単純に次のコマンドを実行しても認識されない場合があります。

phpstan analyse

その場合は、次のように実行します。

vendor/bin/phpstan analyse

Windowsでは、次のように実行できます。

.\vendor\bin\phpstan.bat analyse

phpstan.neonが認識されない

phpstan.neonがプロジェクトルートに配置されているか確認します。

たとえば、次のような構成です。

my-project/
├─ .vscode/
├─ src/
├─ tests/
├─ vendor/
├─ composer.json
├─ composer.lock
└─ phpstan.neon

また、ターミナルでPHPStanを実行しているカレントディレクトリも確認してください。

VSCodeとターミナルで解析結果が異なる

VSCode拡張機能とターミナルで異なるPHPStanを実行していると、解析結果が一致しない場合があります。

たとえば、次のような状態です。

ターミナル
→ プロジェクトのvendor/bin/phpstan

VSCode
→ 別のPHPStan

可能であれば、VSCode、ターミナル、CIのすべてでプロジェクト内のPHPStanを利用するよう統一するとよいでしょう。

VSCodeとPHPStanのおすすめ構成

一般的なPHPプロジェクトであれば、次のような構成が扱いやすいでしょう。

my-project/
├─ .vscode/
│  └─ settings.json
├─ src/
│  ├─ User.php
│  └─ Product.php
├─ tests/
├─ vendor/
├─ composer.json
├─ composer.lock
└─ phpstan.neon

phpstan.neonには、まず解析レベルと対象ディレクトリを設定します。

parameters:
    level: 8

    paths:
        - src
        - tests

新規プロジェクトで厳しい解析を行いたい場合は、次のようにする方法もあります。

parameters:
    level: max

    paths:
        - src
        - tests

PHPStanは、Composerでインストールします。

composer require --dev phpstan/phpstan

まずはターミナルから次のコマンドが正常に動作することを確認します。

vendor/bin/phpstan analyse

その後、必要に応じてVSCode用のPHPStan拡張機能を導入します。

基本的な利用の流れは次のとおりです。

PHPコードを書く
↓
PHPStanで解析する
↓
問題を確認する
↓
コードを修正する
↓
再度解析する

VSCode拡張機能を利用すれば、この流れをエディタ上で効率化できます。

特に重要なのは、最初にPHPStan単体をターミナルから正常に実行できる状態にすることです。

PHPStan本体が正常に動いていることを確認してからVSCode連携を設定すれば、問題が起きた際に原因を切り分けやすくなります。

チーム開発では、Composer ScriptsやCIにもPHPStanを組み込み、ローカル環境、VSCode、CIで同じPHPStanと同じ設定ファイルを利用するよう統一すると、コード品質を安定させやすくなります。

以上、VSCodeでPHPStanを利用する方法についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次