xdebugをブラウザーからトリガーするための基本中の基本(設定に躓いてる人用)
はじめに
xdebugはブラウザーからトリガーして使う場合若干通信経路が複雑になるのと、最低限この設定が出来てないとxdebug
が有効になってそうなのに全く使えないという事がある。そのためこの記事では設定がうまくいかない場合まず確認することとしてxdebugの設定状況および通信経路に着目し、その通信を確認した後でどのように解決していったらいいのか見て行くものとなっている。
WSL2とかのlinux環境がやっぱり欲しい
XAMPP
に関してはよくわからんのでスルーするとして、
そうなるとWSL2かdockerデスクトップかみたいなのがローカル開発の基本になると思うがいずれにせよ基本的にlocalhost
で通信するのでポートが遮断されているとかのトラブルは起き辛いものだ。ただしここではポートの通信を逐一確認するためにnc
というツールを使って実際の通信状況をデバッグを初める前にしっかり確認しておく所からはじめる。その点でもlinux環境がどうしても必要なため、ここではWSL2に限定した記事にまずはさせていただく。
なお、このツールはubuntu(debian)系だとnetcat-openbsd
という名前になっているので、適時installしておくこと。
sudo apt update && sudo apt install -y netcat-openbsd
$ type nc
nc is hashed (/usr/bin/nc)
こんな感じになればok
WSL2による開発
冒頭で書いた通りwindowsネイティブのphp.exeは取り上げない。
ここではphpのweb開発ではもっとも一般的なlaravelをチュートリアルとして用意する。これもWSL2が導入されていれば簡単に用意する事ができる
大前提
phpは必要なのでapt install php
とかが必要なのはともかくとして、composer
とlaravel
コマンドが導入されていること。これの環境構築に関してはページの無駄なので、ここでは取り上げない
WSL2内でlaravelを適当に用意する
というわけでlaravel
コマンドが使える事を前提として、
laravel new testapp
みたいにして何でもいいのでlaravelのプロジェクトの雛形を展開する。その後で
cd testapp/
php artisan serve
とかすると
$ php artisan serve
INFO Server running on [http://127.0.0.1:8000].
Press Ctrl+C to stop the server
こんな感じになるはずだ。ここでhttp://127.0.0.1:8000にアクセスすると何でもいいのでlaravelの画面が出てくるはずである、エラーでもいい
ここではエラーになってるけどまあ何でもよい
ここでブラウザーを通じてlaravelの画面が表示されているはずで、これに関してはhttp://localhostでもhttp://localhost:8000でも8888でも9000でも何でもいいんだけど、ブラウザーからwebアプリまでの通信は確立されているはずである。この部分に関しては
ブラウザー -> webapp
まで成立している事を意味するわけだが、xdebugはこの先の通信経路の確立が重要なのでここまでは普通に出来ている事が大前提である
xdebug環境の確認(phpinfo)
やはりここではまずxdebug環境が有効になっているかの確認を最初に行っておきたい。これはpublic/info.phpとかなんでもいいので好きなファイルを作成して確認するのが一応鉄板だろう
<?php phpinfo();
こんな感じで書いてアクセスすればよいはずだ
ここでWSL2+Ubuntu環境だと /etc/php/8.3/cli/php.iniとか /etc/php/8.3/cli/conf.dといったファイルをphp.iniの設定ファイルあるいはディレクトリとして設定されているのがわかる。今回はwebサーバーを経由せずartisan serve
とか叩いているのでcliっていう風になるわけだが、いずれにせよ、phpinfo()
内でxdebug
が有効になっていない場合がほとんどだと思うので、有効になっていない場合は以下のように拡張をinstallする必要があるだろう。
sudo apt install php-xdebug
php-xdebug
というのは一種の仮想パッケージというかメタパッケージのようなもので実際にはphp8.3-xdebug
とかのようにバージョンに応じた拡張が入る、いずれにせよ以下のようにしてどこにinstallされたのかを確認可能である
$ dpkg -L php8.3-xdebug
/.
/etc
/etc/php
/etc/php/8.3
/etc/php/8.3/mods-available
/etc/php/8.3/mods-available/xdebug.ini
/usr
/usr/lib
/usr/lib/php
/usr/lib/php/20230831
/usr/lib/php/20230831/xdebug.so
/usr/share
/usr/share/doc
/usr/share/doc/php8.3-xdebug
/usr/share/doc/php8.3-xdebug/changelog.Debian.gz
/usr/share/doc/php8.3-xdebug/copyright
さて、ここでは /etc/php/8.3/mods-available/xdebug.ini に設定ファイルがある事がわかるので、これを編集する。 /etc/php/8.3/cli/conf.d ではないの?と思われた方は鋭いが、
$ ls -l /etc/php/8.3/cli/conf.d | grep xdebug
lrwxrwxrwx 1 root root 38 Jun 13 09:40 20-xdebug.ini -> /etc/php/8.3/mods-available/xdebug.ini
このような形でリンクされているので大丈夫な仕様になっている。いずれにせよ以下のように記述する
zend_extension=xdebug.so
[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log
xdebugの環境確認
ここで再度phpinfoを見てみよう
Step Debuggerがentabled
になっている
127.0.0.1:9003とかになっている
xdebug.mode
とxdebug.start_with_request
を確認
このように設定項目が正しく反映されているか十分確認すること
デバッガーが動作しているか確認する
ここでwebアプリの通信は前に記したように
ブラウザー -> webapp
こうなっているが、xdebugの通信は
ブラウザー -> webapp -> デバッガ
となっておりwebアプリからデバッガーに接続してくる。ここでの経路が先程セットした127.0.0.1:9003
であり、ここの接続経路が確立できないと全くデバッグができない。ここが最初のちょっと難しい所だ
つまり127.0.0.1:9003
でデバッガが待ち受ける必要があるのだが、通常は今日日vscode
を使う事になるだろう(phpstorm
はよくわからん)。ただvscode
だろうがphpstorm
だろうがvdebug
だろうが何にせよ指定された経路(ここでは127.0.0.1:9003
)の通信が確立してないとまったく動作しようがないので、まずここでは冒頭で導入したnc
コマンドを媒介させて通信できているかどうかを確認するのがトラブルが少ないだろうと思う
ここでss
コマンドで現在の状態を確認すると
$ ss -tlpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:42297 0.0.0.0:*
LISTEN 0 1000 10.255.255.254:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:8000 0.0.0.0:* users:(("php8.3",pid=2688,fd=7))
こんな感じになっていた。ここでさらに1つターミナルを起動し
nc -l 127.0.0.1 9003
と打つとターミナルが応答待ちになって何も表示されない状態となるが、この時点でssを再度見ると
$ ss -tlpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 1 127.0.0.1:9003 0.0.0.0:* users:(("nc",pid=4026,fd=3))
LISTEN 0 4096 127.0.0.1:42297 0.0.0.0:*
LISTEN 0 1000 10.255.255.254:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:8000 0.0.0.0:* users:(("php8.3",pid=2688,fd=7))
このように127.0.0.1:9003
が表示されている。この時点で再度info.php的なものをリロードしてみると...?
こんな感じでxmlが表示され、なおかつブラウザーがグルグル回ってる状態になるはずだ
停止している
ここでnetstatをCtrl+cとかで割り込むとブラウザーは素直に表示に戻ることだろう。ここまで出来て初めてxdebugが機能する準備が整ったということになる。
vscodeで確認してみよう
vscode + wsl2の場合はwsl拡張が必須だから導入しておくこと
また、phpdebugも必要なのでこれも導入する。2つあるけどポピュラーな方で
WSL2への接続
ctrl+shift+pとかで接続し、当該のlaravelディレクトリーを開くと以下のようになるはずだ
ただし、開いただけでは9003はlistenしていない、ってことはvscode開いただけではvscodeでデバッグできないというのがこの時点で理解可能なはずである。
ss -tlpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 511 127.0.0.1:41061 0.0.0.0:* users:(("node",pid=4359,fd=18))
LISTEN 0 4096 127.0.0.1:42297 0.0.0.0:*
LISTEN 0 1000 10.255.255.254:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:8000 0.0.0.0:* users:(("php8.3",pid=2688,fd=7))
9003が見当たらない
vscodeでデバッグするためには.vscode/launch.jsonが必要
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/your/path/to/testapp": "${workspaceFolder}"
}
}
]
}
こんな感じで書いて、保存する。/your/path/to/ は正しくWSL2の環境と合わせること。
さらにinfo.phpを改変し
<?php
$var = "This is a test variable";
var_dump($var);
phpinfo();
こんな感じにしてみよう。この段階でvscodeのデバッグしたい行に赤丸を付けることができる。これがブレークポイントというやつになる
デバッグしてみる
左の三角みたいになってる奴から辿ってListen for Xdebugの左の緑の三角を押す。この時点でまずssで確認してみよう
$ ss -tlpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 511 127.0.0.1:41061 0.0.0.0:* users:(("node",pid=4359,fd=18))
LISTEN 0 4096 127.0.0.1:42297 0.0.0.0:*
LISTEN 0 1000 10.255.255.254:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:8000 0.0.0.0:* users:(("php8.3",pid=2688,fd=7))
LISTEN 0 511 *:9003 *:* users:(("node",pid=7768,fd=19))
するとこんな感じで9003が見えるようになった。この状態でinfo.phpを開いてみると
画面が停止している
ここでは新たに開き直してgoogleが見えてるけどいずれにせよ画面が停止し何も表示されない、これが正解だ、画面が停止しない場合はここにいたるまでの何かの設定がおかしい可能性がある。
vscodeに戻ると、当該の行で止っている。左の変数を見るとまだ $var には何も入っていないが、ステップオーバーすると
こんな感じで変数の内容が左ペインに表示されているし、下のパレットでも$var
とか打つと
このようになるというわけだ
デバッグを停止し、9003とかのlistenをやめるには
赤い四角形を押すとよい
以上
ここまで主にvscodeを使ったブラウザデバッグ手法を見てきたが、これはphpstorm(使ったことないけど)でも、vdebugなんかでも同じ仕組みになっているはずだから、まずサーバーからデバッガへの通信をまともに受信できているのかの確認がどうしても必須であると言える。そのためにはnc
コマンドは非常に強力であり、本番のデバッガを媒介させる前にこのコマンドで正しくデバッガー用のxmlを受信できているのか確認しておくのが非常に重要になるだろう。これはlocalネットワークでトラブルが少ないwsl2や、たぶんXAMPPとかだけで開発しているとあんまりハマらないところかもしれないが、たとえばこれがdockerコンテナーからのデバッグ、さらにはリモートから直接デバッグしたいとかいう場合でも結局このTCP通信さえ確立してしまえば出来るということになるはずなわけで、この通信の確認は非常に便利でありまた重要であるわけだ。
ここではおそらくもっとも簡単なWSL2環境のみ取り上げて解説したが、そのうちもうちょっと複雑な開発環境に対するデバッガの起動方法も書く、かも。需要は限りなく少ないはずではあるが!
Discussion