2026年7月21日
2026年7月21日
PHPのデバッグツールXdebugの設定方法|インストールからVS Code・Dockerでのステップ実行まで
Xdebugは、PHPのコードを1行ずつ止めながら変数の中身を確認できる「ステップ実行」を可能にする拡張機能です。設定の要点は、xdebug.mode=debug で機能を有効にし、xdebug.client_host と xdebug.client_port(既定9003)でエディタの待ち受け先を正しく指定し、エディタ側でサーバーとローカルのパスを対応づけることの3つです。この記事では、Xdebug 3系を前提に、インストール、php.iniの設定、VS Codeでの接続、Docker環境での注意点、ブレークポイントで止まらないときの確認手順までを説明します。
Xdebugでできること
var_dump() やログ出力でのデバッグは手軽ですが、確認したい変数ごとにコードを書き換える必要があります。Xdebugを使うと、エディタ上でブレークポイントを置き、そこで処理が止まった状態で、変数・配列の中身や呼び出し履歴(スタック)を見ながら1行ずつ進められます。
Xdebug 3では、使う機能を xdebug.mode で選びます。主なモードは次のとおりです。
debug… ステップ実行(この記事の主題)develop… エラー時のスタックトレース表示やvar_dump()の見やすい出力profile… 関数ごとの処理時間を計測し、ファイルに出力するcoverage… PHPUnitなどでコードカバレッジを取るtrace… 関数呼び出しの記録をファイルに出力するoff… 何もしない
debug,develop のようにカンマ区切りで複数指定できます。Xdebug 2系とは設定名が大きく変わっているため、古い記事にある xdebug.remote_enable や xdebug.remote_port=9000 は3系では使えません。ネットで見つけた設定をそのまま貼る前に、名前が3系のものか確認してください。
インストール
Xdebugは開発環境だけに入れます。読み込むだけで処理が遅くなるため、本番サーバーには入れないのが原則です。
Debian/Ubuntu系
sudo apt install php-xdebug
# 特定のバージョン向けなら php8.3-xdebug のようにパッケージ名が分かれていることがある
PECLを使う場合(macOSのHomebrew版PHPなど)
pecl install xdebug
Windows
Xdebug公式サイトには、phpinfo() の出力を貼り付けると、使っているPHPに合うDLLと設定手順を案内してくれるページがあります。PHPのバージョン、スレッドセーフ版かどうか、64bit/32bitの組み合わせを間違えると読み込めないため、自分で選ぶより案内に従うほうが確実です。
Dockerの公式PHPイメージ
FROM php:8.3-apache
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
インストールできたかは、次のコマンドで確認します。
php -v
# 出力に "with Xdebug v3.x.x" のような行があれば読み込まれている
Webサーバー側(PHP-FPMやApache)はCLIと別の設定ファイルを読んでいることがあるため、Web側は phpinfo() か、後述する xdebug_info() で確認します。
php.iniの設定
Xdebug用の設定ファイル(例: Debian/Ubuntuでは /etc/php/8.3/mods-available/xdebug.ini。パスは環境で異なります)か、php.iniに次のように書きます。
zend_extension=xdebug
xdebug.mode=debug,develop
xdebug.start_with_request=trigger
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log
各項目の意味は次のとおりです。
zend_extension… Xdebugは通常のextension=ではなくzend_extension=で読み込みます。パッケージで入れた場合は、すでに書かれていることが多いです。xdebug.start_with_request…yesにするとすべてのリクエストでエディタへの接続を試みます。triggerにすると、後述のトリガーが付いたリクエストだけでデバッグが始まるため、普段の動作が軽くなります。xdebug.client_host/xdebug.client_port… Xdebugは「PHPのサーバーからエディタへ」接続しに行きます。エディタが動いているマシンのアドレスとポートを指定します。xdebug.log… 接続の成否が記録されます。つながらないときの調査に使うので、最初は設定しておくのがおすすめです。
設定を変えたら、PHP-FPMやApacheを再起動します。CLIは次の実行から反映されます。
トリガーの付け方
start_with_request=trigger のときは、リクエストに XDEBUG_TRIGGER という名前のGETパラメーター・POSTパラメーター・Cookieのどれかを付けるとデバッグが始まります。
http://localhost:8080/sample.php?XDEBUG_TRIGGER=1
CLIのスクリプトやWP-CLIをデバッグするときは環境変数で指定できます。
XDEBUG_TRIGGER=1 php script.php
# モードだけ一時的に切り替える場合
XDEBUG_MODE=debug XDEBUG_TRIGGER=1 php script.php
画面のある操作やAjaxをデバッグするなら、Cookieを付けるブラウザ拡張を使う方法もあります。拡張機能はいくつかあり、提供元や更新状況が変わることがあるため、使う前に配布元を確認してください。
xdebug_info()で設定を確認する
Xdebug 3には、現在の設定と状態を一覧表示する xdebug_info() 関数があります。
<?php
// xdebug-check.php(開発環境だけで使い、確認後に削除する)
xdebug_info();
有効なモード、client_host の値、直前の接続の試行結果などが表示されます。CLIとWebの設定の食い違いもここで分かります。
VS Codeで接続する
VS Codeでは、Xdebugの開発チームが公開している「PHP Debug」拡張機能を使います。インストール後、プロジェクトに .vscode/launch.json を作ります。
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003
}
]
}
デバッグのパネルでこの構成を選んで開始すると、VS Codeが9003番ポートで待ち受けます。その状態でトリガー付きのURLを開き、ブレークポイントを置いた行で止まれば成功です。
PhpStormにもXdebugの待ち受け機能が組み込まれています。メニュー名や設定画面の構成はバージョンで変わるため、JetBrainsのドキュメントで「Xdebug」の項目を確認してください(2026年10月現在)。
DockerやVMで動かす場合
コンテナや仮想マシンの中でPHPが動いている場合、2つの点でつまずきやすくなります。
client_hostの指定
コンテナ内の 127.0.0.1 はコンテナ自身を指すため、ホストのVS Codeには届きません。Docker Desktop(Windows・macOS)では host.docker.internal という名前でホストに接続できます。
xdebug.client_host=host.docker.internal
LinuxのDocker Engineではこの名前が既定では使えないため、Docker Composeで次のように追加します。
services:
php:
build: .
extra_hosts:
- "host.docker.internal:host-gateway"
パスの対応づけ(pathMappings)
コンテナ内では /var/www/html/index.php、手元では C:\project\index.php のように、同じファイルのパスが異なります。エディタに対応関係を教えないと、Xdebugが接続してもブレークポイントの位置が合わず止まりません。
{
"name": "Listen for Xdebug (Docker)",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
}
}
WordPressのプラグイン開発でよく使われる @wordpress/env(wp-env)には、wp-env start --xdebug のようにXdebugを有効にして起動するオプションがあります。この場合も、コンテナ内のプラグインのパス(例: /var/www/html/wp-content/plugins/プラグイン名)を手元のフォルダに対応づけます。
ブレークポイントで止まらないときの確認手順
原因として多い順に確認します。
- Xdebugが読み込まれていない、またはモードが違う
xdebug_info() を開き、Web側でXdebugが有効か、debug モードになっているかを見ます。CLIでは有効なのにWebでは無効、というケースがよくあります。
- 接続先が違う
xdebug.log に Could not connect to debugging client のような行があれば、Xdebugは接続を試みたものの届いていません。client_host の値、エディタが待ち受けを開始しているか、ポートが9003で一致しているか(古い設定の9000が残っていないか)を確認します。
- ファイアウォールで止められている
VMや別マシンからの接続では、エディタ側のOSのファイアウォールが9003番ポートへの受信を止めていることがあります。
- トリガーが付いていない
start_with_request=trigger の場合、トリガーの無いリクエストではデバッグが始まりません。ログに何も記録されないときはこれを疑います。
- パスの対応づけがずれている
接続はできているのに止まらない場合は、pathMappings の左側(サーバー側のパス)が実際のパスと一致しているかを確認します。
本番環境での扱い
Xdebugは本番サーバーに入れないことを基本にしてください。xdebug.mode=off でも拡張機能の読み込み自体による負荷はわずかに残ります。さらに、debug モードを有効にしたまま公開すると、トリガーを付けたリクエストによって外部へデバッグ接続が試みられることになり、セキュリティ上も望ましくありません。本番で処理の遅さを調べたい場合は、ステージング環境に同じデータを用意して profile モードで計測するか、アプリケーション側のログで調べます。
まとめ
- Xdebug 3は
xdebug.modeで機能を選ぶ。旧2系のremote_*設定やポート9000は使わない zend_extension=xdebugで読み込み、client_host・client_port=9003でエディタの待ち受け先を指定するstart_with_request=triggerにして、XDEBUG_TRIGGERを付けたリクエストだけでデバッグする- Dockerでは
host.docker.internalとpathMappingsの設定がつまずきどころ - つながらないときは
xdebug_info()とxdebug.logで、読み込み・接続先・トリガー・パスの順に確認する - 本番サーバーには入れない