こんにちは!開発現場で日々PHPと格闘していると、頭を抱えたくなる瞬間がありますよね。「画面が真っ白になった」「なぜか期待した値が入っていない」。そんな時、`var_dump()`や`echo`でデバッグの文字を画面に大量に出力していませんか?
それを今すぐ卒業できるのが、PHP最強のデバッガ「Xdebug」です。
Xdebugを正しく導入すれば、コードの途中で処理をピタッと止め、その瞬間の変数の中身をすべて覗き見したり、1行ずつコードを進めながら「どういうルートで処理が流れているのか」を完全にコントロールできるようになります。これをマスターすれば、毎日のコーディングやバグ調査が劇的に楽になりますよ。
ただ、このXdebug、非常に強力であるがゆえに「最初の一歩でなぜか動かない」というトラップにハマりがちです。「設定したのにブレークポイントで止まらない…」と絶望した経験はありませんか?
今回は、そんなXdebugの「動かない」を完全に論理的に解決し、確実な動作確認(Hello World的ステップ実行)までたどり着くための決定版ガイドをお届けします。さあ、一緒にその仕組みのモヤモヤをスッキリ解消していきましょう!
—
そもそもXdebugとは内部で何をしているのか?
「設定ファイルに呪文を書いたら動くもの」として捉えているうちは、トラブルが起きたときに手詰まりになります。まずは、XdebugがIDE(PhpStormやVS Codeなど)とPHPの間でどのような通信を行っているのか、その裏側のデータフローをイメージしておきましょう。
1. トリガー(きっかけ): ブラウザからリクエストを送る際、CookieやURLクエリパラメータ(例: `?XDEBUG_SESSION_START=VSCODE`)を付与するか、IDE側から「デバッグ待ち受け状態」のシグナルを送ります。
2. 通信(DBGPプロトコル): PHPの実行エンジン(Zend Engine)に組み込まれたXdebugモジュールが、指定されたIPアドレスとポート(デフォルトは `9003`)に向かってTCPソケット通信を確立します。
3. 制御: IDEはこのTCPコネクションを介して、「ここで処理を一時停止しろ」「この変数のメモリ上の値教えろ」というコマンド(DBGPプロトコル)をPHPに送り、PHPはその結果をIDEに返します。
つまり、「PHP側が正しい宛先に正しく電波(TCP)を飛ばせているか」「IDE側がその電波を待ち受けているか」の2点が揃って初めてデバッグが成立するのです。ここを押さえておけば、トラブルシューティングは怖くありません。
—
【絶対解決】Xdebugが動かないときの原因特定チェックリスト
Xdebug導入時に初心者が必ずハマる3大落とし穴を、論理的な解決策とともに順に潰していきましょう。自分の環境と照らし合わせてみてください。
チェック1: `php.ini` の記述ミス・バージョン差異
Xdebugはバージョン3(現行の主流)とバージョン2で設定ディレクティブが大きく変わっています。古いネット記事をコピペすると、これだけで動きません。
また、CLI(コマンドライン)とWebサーバー(Apache/Nginx/Built-in server)で読み込んでいる `php.ini` が別々なのはよくあるミスです。
正しい設定例(Xdebug v3用)
お使いの環境の `php.ini` の末尾に、以下の設定が正しく入っているか確認してください。
[xdebug]
; Xdebugをデバッグモードで有効化する
xdebug.mode = debug
; リクエスト時に自動でデバッグを開始する(開発環境では1が便利)
xdebug.start_with_request = yes
; IDE(VS CodeやPhpStorm)が待ち受けているホストIP
xdebug.client_host = “127.0.0.1”
; Xdebug 3でのデフォルトポート(バージョン2の9000から変更されています!)
xdebug.client_port = 9003
; ログ出力先(動かないときはここを見るのが一番の近道です)
xdebug.log = “/tmp/xdebug.log”
xdebug.log_level = 7
> プロからの知見: 設定を変えたら、必ずWebサーバー(Apache/Nginx)やPHP-FPMの再起動を行ってください。CLIの場合は不要ですが、ビルトインサーバー (`php -S`) の場合はプロセスを立ち上げ直す必要があります。
—
チェック2: ポート番号の競合(お前は誰だ?)
「設定は完璧なはずなのに、ログを見るとエラーが出ている…」そんな時はポートの競合を疑ってください。
- 症状: `php-fpm` や `Apache` の起動時にポート `9003` がすでに使用されている、またはIDE側でコネクションが確立できない。
- 原因: 他のプロセスがすでに `9003` を掴んでいるか、Dockerコンテナ環境でホスト側とポートフォワーディングが正しく設定されていない。
調査コマンド(Mac / Linux)
現在、ポート9003が何に使われているかを確認するには、ターミナルで以下を実行します。
9003ポートを使用しているプロセスを特定する
lsof -i :9003
もし意図しないプロセスが動いている場合は、そのプロセスを停止するか、`php.ini` の `xdebug.client_port = 9004` のように別の空きポートに変更し、IDE側の待ち受けポートもそれに合わせましょう。
—
チェック3: Docker環境特有の「IPアドレスの壁」
ローカルの物理マシンではなく、Dockerコンテナ上でPHPを動かしている場合、最も多い原因が `xdebug.client_host` の指定ミスです。
コンテナ内から見た「ホスト(あなたのPC)」は `127.0.0.1` ではありません。コンテナにとっての `127.0.0.1` は、コンテナ自身を指してしまうため、IDEに接続が届かないのです。
対策(Dockerの場合)
- Linuxの場合: `xdebug.client_host = 172.17.0.1`(DockerのブリッジネットワークのゲートウェイIP)を指定するか、`php.ini` に以下のマジックワードを設定します。
; DockerやホストのIPを自動解決してくれる便利な特殊値
xdebug.client_host = “host.docker.internal”
- 注意: Docker ComposeのバージョンやOSによっては `host.docker.internal` が使えない場合があるため、その際はネットワーク設定を明示するか、実IPを記述してください。
—
精度高い「Hello World」的ステップ実行で動作確認をする
すべての設定が終わったら、実際にコードを止めて動作確認を行いましょう。今回は多くの開発者が使っている VS Code を例に解説しますが、PhpStormでも概念はまったく同じです。
ステップ1: VS Code側の準備
1. 拡張機能タブから 「PHP Debug」 (Felix Becker氏のものなど)をインストールします。
2. 左側のデバッグアイコン(虫のマーク)をクリックし、`launch.json` を作成します(無い場合は作成ボタンを押すと自動生成されます)。
3. 設定内容が以下のようになっていることを確認します。
{
“version”: “0.2.0”,
“configurations”: [
{
“name”: “Listen for Xdebug”,
“type”: “php”,
“request”: “launch”,
“port”: 9003 // php.iniのclient_portと一致させる
}
]
}
4. デバッグタブの上部にある再生ボタン(緑色の三角)を押し、「Listen for Xdebug」を起動させます(これでIDEがポート9003で待ち受け状態になります)。
—
ステップ2: テスト用PHPスクリプトの用意
プロジェクトのドキュメントルートに、確認用の `index.php` を作成します。
” . htmlspecialchars($message, ENT_QUOTES, ‘UTF-8’) . “
“;
// 処理の終了
exit;
—
ステップ3: 運命の瞬間(ステップ実行)
1. VS Codeの `index.php` の 5行目(`$greeting = …` の行)の左端をクリックし、赤いブレークポイント(●)を灯します。
2. ブラウザからその `index.php` にアクセスします(例: `http://localhost/index.php` またはビルトインサーバーのURL)。
3. ブラウザがロード中のままピタッと止まります。(これが大成功のサインです!)
4. VS Codeの画面に目を戻してみましょう。
画面左側の「変数 (Variables)」パネルを見てください。
- `$greeting` に `”Hello, Xdebug World!”` が入っている。
- `$version` に `3` が入っている。
さらに、上部に現れたデバッグコントロールバーを使って、
- 続行(F5): 次のブレークポイントまで処理を進める
- ステップオーバー(F10): 次の1行を実行する
- ステップイン(F11): 関数の中に入り込んで処理を追う
を自由に行うことができます。この瞬間、あなたはコードの神様になり、プログラムの時間を完全にコントロールできるようになりました。
—
万が一、それでも止まらないときは?(究極のデバッグ手法)
もし上記をすべて試してもブレークポイントで止まらない場合、推測で設定をいじるのはやめましょう。Xdebug自身にログを吐かせて、どこで通信が切れているのかを白日の下に晒します。
先ほどの `php.ini` で設定した `xdebug.log` のパス(例: `/tmp/xdebug.log`)をテキストエディタで開いてみてください。
- 「Could not connect to debugging client…」と書かれている場合:
→ IDE側で「Listen for Xdebug」が起動していない、あるいはポート9003がファイアウォール(Windows Defenderやiptablesなど)にブロックされています。
- ログファイル自体が生成されていない場合:
→ PHPがその `php.ini` をそもそも読み込んでいません。`php -i | grep php.ini` や `phpinfo()` を叩いて、正しい設定ファイルが適用されているかを再確認してください。
—
まとめ
Xdebugの導入は、最初は少しだけ配管工事のように複雑に感じるかもしれません。しかし、「PHPがどこに向かって通信しているか」「IDEがどこで待ち受けているか」という通信のパス(道筋)さえクリアにしてしまえば、これほど頼もしい相棒はありません。
一度この快適なデバッグ環境を手に入れてしまえば、二度と `var_dump` や `print_r` の海原に戻ることはできなくなるはずです。ぜひ今回のチェックリストを活用して、あなたの開発環境を最高のものに仕立て上げてくださいね!