PHP のデバッグツールである Xdebug にはリモートデバッグという機能があります。
…というのは言うまでもなく、広く知られていると思います。
しかし、Xdebug の設定をなんとなくコピペで済ませたりしていないでしょうか?
Xdebug のリモートデバッグ設定、理解していますか?
日本語のサイトを検索すると「 xdebug.remote_enable=1
にして、xdebug.remote_host
を xxx にして…」と設定だけが淡々と書かれた情報が多いです。
しかし、設定項目について、それぞれの意味を理解していないとトラブル時の対処が難しくなります。
リモートデバッグとは何か?
リモートデバッグ (Remote Debugging) とは、実行中の PHP とは別の場所にデバッグを制御するものが存在する 方式です。
よくある環境だと、次のように図示できます。
PHP 本体とは別の場所で動いてる方 がリモートです。
この図だと PHPStorm 側がリモートというわけです。
ここでは PHP 開発用のツールである PHPStorm を例として出していますが、Xdebug を動かすのに PHPStorm が必要というわけではありません。
PHPStorm 以外にも Xdebug のリモートデバッグを行えるツールはたくさんあります。
リモート・セッション
デバッグの制御を開始するには、PHP 本体側とリモートをつなぐ必要があります。
この一連の接続を「リモート・セッション」と呼びます。
リモートデバッグを有効にする
初期値ではリモートデバッグは無効になっています!
したがって、次の設定値を 1
にする必要があります。
設定 | 役割 | 初期値 |
---|---|---|
xdebug.remote_enable |
1 にするとリモートデバッグが有効になる |
0 |
リモートへの接続設定
Xdebug 側からリモートにつなぐために、どこにつなぐのか? という設定が必要です。といっても、単純な TCP 接続なのでホストとポート番号のみです。
設定 | 役割 | 初期値 |
---|---|---|
xdebug.remote_host |
つなぎ先のホスト名 | localhost |
xdebug.remote_port |
つなぎ先のポート番号 | 9000 |
たとえば、PHP本体とリモート(PHPStorm等)が同じマシンにある場合は初期値のままで使える、ということになります。
PHP を実行しているのが同じマシンではなく、Docker のコンテナ内にある!といった場合は xdebug.remote_host
を変えればOKです。
Xdebug のリモート・セッションはいつ始まっていつ終わるのか?
xdebug.remote_enable=1
にすると、すぐにセッションが始まるわけではありません。
php-fpm のように、HTTPリクエストを受け付ける方式の場合 XDEBUG_SESSION_START=xxx
というパラメータを付けてアクセスすると、はじめて Xdebug のリモート・セッションが ON になります。
xxx
の部分は任意の名前で OK です。
▼ 実際に XDEBUG_SESSION_START
ありなしで比べてみるとわかります
しかし、常に自動で開始させることもできます。
xdebug.remote_autostart=1
を設定するとパラメータがなくても自動的にセッションが始まるようになります。
設定 | 役割 | 初期値 |
---|---|---|
xdebug.remote_autostart |
1 にすると常にセッションを自動開始する |
0 |
一度セッションが始まると、XDEBUG_REMOTE_SESSION
という Cookie がセットされ、それが残っている限りはずっとセッションが続きます。
では、セッションはいつ終わるのでしょうか?
XDEBUG_SESSION_STOP
というパラメータをつけてアクセスすると、セッションを止めることができます。また、Cookie の有効期限が切れるとセッションも切れます。ここの有効期限は xdebug.remote_cookie_expire_time
で調整できます。
設定 | 役割 | 初期値 |
---|---|---|
xdebug.remote_cookie_expire_time |
XDebug のセッションを維持する Cookie の有効期限 | 3600 |
Xdebug のセッション開始モード( req
と jit
)
基本、セッション開始は上記のやり方で即座に開始されます( req
モードといいます)が、これを エラーが初めて起こったときに開始する ように変更することもできます。
このエラーが起こって初めてセッションを開始するモードを jitモード といいます。
設定 | 役割 | 初期値 |
---|---|---|
xdebug.remote_mode |
jit にするとエラーが初めて起こったときにセッションを開始する |
req |
jit
モードにすると、XDEBUG_SESSION_START
パラメータは無視され、エラー発生直後で必ずセッションがつながります。
▼ 試しにわざとエラーを起こしてみるとこのようになりました。XDEBUG_SESSION_START
パラメータを与えていないのにデバッグ制御ができているのがわかります。
(応用編)複数のリモートをつなぐには?
ひとつの PHP に対して複数のリモートセッションをつなぐ方法もあります。xdebug.remote_host
で決定するのではなく、PHPにアクセスした側の IP アドレスに自動的につなぎにいってくれる 機能があります。この機能は xdebug.remote_connect_back=1
にすることで有効になります。
(※ただし、HTTP ヘッダから IP アドレスを取る仕組みなので CLI 実行の場合はうまく動きません)
設定 | 役割 | 初期値 |
---|---|---|
xdebug.remote_connect_back |
1 にするとPHPにアクセスした側の IP アドレスに自動的につなぎにいってくれる |
0 |
この設定を ON にすると、xdebug.remote_host
は無視されます。
(応用編) 間にルーターなどがあり、connect_back
が使えない場合
複数リモートを管理する中間サーバー (DBGp Proxy) を立てる必要があります。
ここについてはすでに Qiita にすばらしい記事があるので参照すると良いでしょう
【PHP】リモートマシンのデバッグを、「複数人で」やる【Xdebug×DBGpProxy】
Xdebug リモートデバッグの設定値まとめ
この記事で紹介した xdebug.remote_...
の設定値を振り返ってみます。
設定 | 役割 | 初期値 |
---|---|---|
xdebug.remote_enable |
1 にするとリモートデバッグが有効になる |
0 |
xdebug.remote_host |
つなぎ先のホスト名 | localhost |
xdebug.remote_port |
つなぎ先のポート番号 | 9000 |
xdebug.remote_autostart |
1 にすると常にセッションを自動開始する |
0 |
xdebug.remote_cookie_expire_time |
XDebug のセッションを維持する Cookie の有効期限 | 3600 |
xdebug.remote_mode |
jit にするとエラーが初めて起こったときにセッションを開始する |
req |
xdebug.remote_connect_back |
1 にするとPHPにアクセスした側の IP アドレスに自動的につなぐようになる。よって xdebug.remote_host は無視される |
0 |
参考になるサイト
公式ドキュメントがやはりいちばん網羅的でわかりやすいです。英語ですが。