こんにちは!日々のPHP開発、お疲れ様です。
皆さんは、大規模なレガシーコードの改修や、複数人での開発の最中に「あれ、このメソッドの引数、本当にこの配列の形で合ってるんだっけ…?」「実行してみたら `null` ポインタ例外で落ちた!」という絶望を味わったことはありませんか?
PHPは動的言語としての柔軟性を持つ一方で、システムが巨大化するほど、頭の中だけで型を追うのが限界を迎えます。
「PhpStormを買ったから、もうIDEが賢くエラーを出してくれるはず!」——そう思っていませんか? 確かにPhpStormの標準インスペクション(静的解析)は非常に強力です。しかし、フレームワーク独自の魔術的なメソッドや、複雑なジェネリクス(Generics)、高度な配列の形状(Shape)の推論においては、IDE単体ではどうしても「限界」が訪れます。
そこで登場するのが、外部の超強力な静的解析エンジンである PHPStan や Psalm です。
今回は、PhpStormの中にこれらの外部エンジンを完璧に統合し、「CI(GitHub Actionsなど)のビルド結果を5分間待つ」という無駄な時間をゼロにし、エディタ上でタイピングした瞬間に型エラーを粉砕する最強のワークフローを構築する方法を、優しく丁寧に解説していきます。
これをマスターすれば、あなたの毎日のコーディングは劇的に楽になり、コードの品質はプロのそれへと一気に引き上げられますよ。
—
なぜPhpStormとPHPStan/Psalmを連携させるべきなのか?
まず、「なぜPhpStormがあるのにPHPStanが必要なの?」という疑問にお答えしましょう。
- PhpStormの役割: 開発中の「リアルタイム性」に特化しています。あなたがコードを1文字打つごとに、背後で構文木(AST)を解析し、即座に波線(インスペクション)で警告を出してくれます。人間で言えば「優秀なペアプログラマー」です。
- PHPStan / Psalmの役割: コードベース全体の「厳密性」に特化しています。設定ファイル(Level 0〜9)に基づき、人間が気づきにくい潜在的なバグ、型安全性の崩壊、到達不可能なコードを徹底的に暴きます。人間で言えば「妥協を許さないシニアアーキテクト」です。
この2つを組み合わせるとどうなるか?
「PHPStanが持つ厳密な解析結果を、PhpStormのエディタ上にリアルタイムでマッピングする」ことが可能になります。CIを回してエラーが出て、修正して、またコミットして……という不毛なループから完全に解放されるのです。
—
1. 基礎セットアップ:プロジェクトへの導入と設定
それでは、実際に手を動かして環境を構築していきましょう。ここでは、業界デファクトスタンダードである PHPStan を例に解説します(Psalmでもアプローチはほぼ一緒です)。
開発環境の前提
- PHP 8.1以上
- Composerがインストールされていること
- PhpStorm(最新版推奨)
ステップ1: PHPStanのインストール
プロジェクトのルートディレクトリで、Composerを使ってPHPStanを開発環境用(`–dev`)としてインストールします。
プロジェクトのルートで実行
composer require –dev phpstan/phpstan
なぜグローバルではなくローカルのプロジェクトごとにインストールするのでしょうか? それは、プロジェクトごとにPHPのバージョンや依存ライブラリ(LaravelやSymfonyなど)のバージョンが異なるため、そのプロジェクト専用の解析ルール(文脈)を正しく解釈させるためです。
ステップ2: `phpstan.neon` の作成
プロジェクトのルートに、PHPStanの設定ファイルである `phpstan.neon` を作成します。ここが静的解析の「頭脳」となる設定です。
parameters:
# 解析の厳格度レベル(0から9まで。最初は5あたりから始めるのがおすすめ)
level: 5
# 解析対象とするディレクトリのパスを指定
paths:
- src
- tests
# 第三者製ライブラリの型定義などを補うための設定(必要に応じて)
# inferPrivatePropertyTypeFromConstructor: true
> 先輩からのアドバイス:
> 最初から最高レベルの `9` に設定すると、数千個のエラーが出て心が折れます。まずは `5` あたりからスタートし、徐々にレベルを上げていくのが挫折しないコツです。
—
2. PhpStormへの統合:プラグインと外部ツールの設定
ここからが本番です。PhpStormにPHPStanをネイティブ統合させます。
ステップ1: プラグインのインストール
PhpStormには、PHPStanを快適に扱うための専用プラグインが用意されています。
1. PhpStormを開き、`Settings` (macOSなら `Preferences`) を開きます。
2. [Plugins] を選択し、Marketplace タブを開きます。
3. 検索窓に 「PHPStan Support」 と入力し、インストールします。
4. IDEを再起動します。
ステップ2: 外部ツール(External Tools)としての登録
プラグインだけでも動きますが、より確実かつ柔軟にPhpStormからPHPStanを呼び出すために、「External Tools」としても登録しておくと非常に便利です。
1. `Settings` から [Tools] > [External Tools] を開きます。
2. `+` ボタン(追加)をクリックし、以下のように設定します。
| 項目 | 入力値 |
| :— | :— |
| Name | `PHPStan` |
| Description | `Run PHPStan static analysis` |
| Program | `$ProjectFileDir$/vendor/bin/phpstan` (プロジェクト内の実行ファイルを指定) |
| Arguments | `analyse –no-progress` |
| Working directory | `$ProjectFileDir$` |
これで、PhpStormのメニューからいつでもワンタッチでPHPStanを実行できるようになりました。
—
3. 精度高い動作確認(Hello World的検証)
正しく連携できているか、あえて「型エラーを仕込んだコード」を作ってテストしてみましょう。
テスト用コードの作成
`src/Calculator.php` というファイルを作成し、以下のコードを記述してください。
add(10, “20”);
}
}
動作確認:エディタ上での魔法の瞬間
1. `src/Calculator.php` をPhpStormで開きます。
2. PHPStanのプラグインやPhpStormのインスペクション設定が正しければ、`”20″` の部分に波線(あるいはPHPStanからの指摘を示すマーカー)が表示されます。
3. ターミナルから先ほど登録した External Tools(または直接コマンド)を実行してみましょう。
vendor/bin/phpstan analyse src/Calculator.php
【実行ログの例】
1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
—— ————————————————–
Line Calculator.php
—— ————————————————–
16 Parameter #2 $b of method App\Calculator::add()
expects int, string given.
—— ————————————————–
[ERROR] Found 1 error
見事にPHPStanが、「`add` メソッドの第2引数は `int` を期待しているのに、`string` が渡されている」というバグを正確に検知しました!
この結果が、CIを待つことなく、あなたのPhpStormのエディタ上でリアルタイムにフィードバックされます。
—
毎日のコーディングが劇的に変わる瞬間
このワークフローを導入した瞬間から、あなたの開発スタイルは以下のようにガラリと変わります。
- 「動かしてみないと分からない」からの脱却: コードを書いているその場で型エラーが潰せるため、デバッグのために `var_dump()` を仕込んだり、ブラウザをリロードしたりする無駄な時間が消滅します。
- リファクタリングの恐怖が消える: 「このメソッドの引数の型を変えたら、どこに影響が出るだろう…」という不安も、静的解析とPhpStormの強力な補完があれば、赤く光るエラーを一つずつ消していくだけで完璧に完了します。
- チーム全体のコード品質の均一化: レビュー時に「ここに型をつけてください」という不毛な指摘をする必要がなくなります。機械がやってくれることは、すべて機械に任せましょう。
—
まとめ
今回は、PhpStormとPHPStanを連携させ、型推論の限界を突破する最強の静的解析ワークフローについて解説しました。
最初は設定項目が多くて面倒に感じるかもしれませんが、一度この環境を作ってしまえば、もう元の「型なき世界」には戻れなくなるほどの圧倒的な安心感を手に入れることができます。
明日からのコーディングが、より快適で、よりエキサイティングなものになりますように。
あなたの開発ライフが素晴らしいものになることを、心から応援しています!