vdebugの使い方と、さらなるxdebugの使い方
defaultのkeyバインド
大体必要なので覚えといてください。
ステップ実行の用語について
この辺の用語もvdebugに限らず共通語みたいなもんなんで、覚えといて。
で、これはどういう事かをよくわかるスニペットを出してもらった。実行環境は前の記事
とか
とかを参考にセットアップくださいよ〜。なお、ここではdockerを使っとる。
今一度ステップ実行を観察する(chatgptが出力してきたスニペットで)
<?php
// デバッグログファイルのパス
$logFile = 'debug.log';
// ログ関数
function debugLog($message) {
global $logFile;
file_put_contents($logFile, date('Y-m-d H:i:s') . ' - ' . $message . PHP_EOL, FILE_APPEND);
}
// デバッグ対象の関数
function exampleFunction($a, $b) {
debugLog("Entering exampleFunction with arguments: a=$a, b=$b");
$result = $a + $b;
debugLog("Calculated result: $result");
return $result;
}
// メイン処理
$a = 5;
$b = 10;
debugLog("Starting main process with values: a=$a, b=$b");
$result = exampleFunction($a, $b);
debugLog("Final result: $result");
まあ適当な関数を作ってログっていくような奴だね
step overしてみる
としといてconnectionを待機すると
ここで停止する。その後F2でstep overする
さらにF2でsteo overする
終了。左下に変数がごちゃっと出ている。そして書かれたログは
public/debug.log
2024-06-10 04:32:14 - Starting main process with values: a=5, b=10
2024-06-10 04:32:14 - Entering exampleFunction with arguments: a=5, b=10
2024-06-10 04:32:14 - Calculated result: 15
2024-06-10 04:32:14 - Final result: 15
このようにstep overは関数を一気に跨いでいく時に使う
step intoしてみる
なんとなく想像つきそうだけど、まず待機してbreakpointまで持っていく
ここでStep Intoする、つまりF3だね
するとdebugLog() 関数の中に入っていく
何回かF3を押して関数をなめまわして戻ってくる
この時点でのログは
2024-06-10 04:56:15 - Starting main process with values: a=5, b=10
などなっておりさらにF3を押してすすめるとじゃんじゃんすすんでいく。
ここで重要なのはログを書きこむ作業を1行ずつ確認できるということで、これはstep overと異なるところだ。step intoは関数の中までじっくり見ていくので、より詳細な情報が欲しい場合はこれで行う。
step out
これはStep Intoで入った関数を強制的に抜けるときに使ってみて(手抜き)
その他のxdebugの使い方
<plaintext>
<?php
function func1() {
sleep(1); // 1秒待つ
return "Fast function complete!\n";
}
function func2() {
sleep(3); // 3秒待つ
return "Slow function complete!\n";
}
function func3() {
sleep(2); // 2秒待つ
return "Medium function complete!\n";
}
function execute() {
echo func1();
echo func2();
echo func3();
}
execute();
このexecute() という関数が何かおせえんだけど、どの関数が遅いのかよくわからんなーという場合があるじゃないすか。もちろんここではログを出してるのでfunc1() func2() func3() どれが一番遅いのかすぐわかるんだけどさ。
これをxdebugを使ってprofileしてみる。なお設定は前回のdockerを用いた例を使っているから一応そこは勘弁してほしい
zend_extension=xdebug.so
[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
この設定を
zend_extension=xdebug.so
[xdebug]
;xdebug.mode=debug
xdebug.mode=debug,profile
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.output_dir=/var/www/html/profiler_output
とかにして、profiler_outputディレクトリ を作ってサーバーが書き込める設定にしておく
すると profiler_output/cachegrind.out.9 的なファイルが生成されているから、それを眺めてみると
version: 1
creator: xdebug 3.3.2 (PHP 8.3.8)
cmd: /var/www/html/public/test.php
part: 1
positions: line
events: Time_(10ns) Memory_(bytes)
fl=(1) php:internal
fn=(1) php::sleep
5 100011646 0
fl=(2) /var/www/html/public/test.php
fn=(2) func1
4 2035 32
cfl=(1)
cfn=(1)
calls=1 0 0
5 100011646 0
fl=(1)
fn=(1)
10 300011360 0
fl=(2)
fn=(3) func2
9 1687 32
cfl=(1)
cfn=(1)
calls=1 0 0
10 300011360 0
fl=(1)
fn=(1)
15 200011776 0
fl=(2)
fn=(4) func3
14 1718 32
cfl=(1)
cfn=(1)
calls=1 0 0
15 200011776 0
fl=(2)
fn=(5) execute
19 3988 0
cfl=(2)
cfn=(2)
calls=1 0 0
20 100013681 32
cfl=(2)
cfn=(3)
calls=1 0 0
21 300013047 32
cfl=(2)
cfn=(4)
calls=1 0 0
22 200013494 32
fl=(2)
fn=(6) {main}
1 1173 48
cfl=(2)
cfn=(5)
calls=1 0 0
25 600044211 96
summary: 600061732 572752
これは人に見辛いのでwebgrindを使う。これまたdockerで起動する。ポートを新たに使うので必要に応じてport貫通の処理を行う事。
webgrind
まあ要するにxdebugのprofileデータparserみたいなもんだな。ここではdockerイメージを使う
wodby/webgrind
色々あるんですが今回はarm64対応のこれにした。いずれにせよこんな感じで起動する
docker run -d -p 8080:8080 -v $(pwd)/profiler_output:/tmp wodby/webgrind
これはとりあえず内部のコンテナport8080で起動しているのを自分ホストにbindしてるのと、hostの profile_output を /tmp にmountしている。この辺はドキュメントに従ってやるとよい
アクセスしてみると…
うまいこといってれば
こんな画面になり、右側に解析対象ファイルが見える。いくつか見える事もあるけど今回はid:9なのでそれを見てみよう。
そうすると
このようにサマリーがみえる。クリックで開閉するんだけど何か連打すると増えるなwバグかも。ま、いずれにせよ
こうなってるわけ、で、ここでもう一度先のsnippetを見れば
<?php
function func1() {
sleep(1); // 1秒待つ
return "Fast function complete!\n";
}
function func2() {
sleep(3); // 3秒待つ
return "Slow function complete!\n";
}
function func3() {
sleep(2); // 2秒待つ
return "Medium function complete!\n";
}
function execute() {
echo func1();
echo func2();
echo func3();
}
execute();
解析のサマリーをchatgptに解説してもらおう
graph
これ便利なんで使ってみてね
まとめ
ま、どうしてもこの手の解説記事だと実戦の詳細な情報を出すわけにはいかなくてダミーのsnippetくらいしか出ないけどある程度経験ある人はこれを基に展開する事は十分に可能だと思います、逆に言えばそれが経験値ってことだよね。では。