Xdebug の使い方
PHP での開発効率を向上させるために、PHP 自体に機能を追加するという方法があります。
Xdebug とは?
Xdebug は、PHP での開発効率を向上させるためのさまざまな機能を提供してくれる PHP の拡張機能(エクステンション)です。 Xdebug でできることは下記の6つです。
- ステップ実行:スクリプトの実行中に IDE またはエディターでコードをステップ実行
- 開発ヘルパー:
var_dump()
関数の拡張、スタックトレース表示の拡張 - 関数トレース:すべての関数の呼び出しを追跡してファイルに保存
- プロファイリング:PHP アプリケーションのパフォーマンスを分析
- ガベージコレクション統計:PHP の内部ガベージコレクターの統計を確認
- コードカバレッジ解析:PHPUnit でテスト対象のコードがどれくらいテストされたかを解析
Xdebug のインストール
Xdebug をインストールする方法はいろいろありますが、ここでは Windows の XAMPP 環境にインストールする方法を紹介します。
Xdebug をダウンロードする
Xdebug は PHP の拡張機能(エクステンション)です。 Windows の場合は .dll ファイルになります。
公式サイトのダウンロードページから、環境にあった .dll ファイルをダウンロードします。 ベータ版もありますが、ちゃんと動きませんので、安定版(beta とついていないもの)がオススメです。 間違ったバージョンをダウンロードしてしまうと動きませんので注意してください。
どのバージョンをダウンロードすればいいかわからない場合
どのバージョンをダウンロードすればいいかわからない場合は、Xdebug の公式サイトに調べてくれるページがありますので、それを使ってみましょう。 便利ですが、使い方はかなり特殊です。
-
まず、動作させたい環境で
phpinfo()
を表示します(コマンドラインからphp -i
でも良いです)。 その結果を、まるごとコピーします。 -
そしてその内容を公式サイトの Installation Wizard のページに貼り付けて、「Analyse my phpinfo() output」ボタンを押します。
-
すると、一致しているバージョンを教えてくれるので、その .dll ファイルをダウンロードします。
PHP の拡張機能として設定する
.dll ファイルがダウンロードできたら、その .dll ファイルを PHP の拡張機能として読み込むよう設定します。
-
まず、ダウンロードした .dll ファイルを PHP のエクステンションディレクトリ("C:\xampp\php\ext")に移動させます。
-
ファイル名を "php_xdebug.dll" に変更します(つまり、"C:\xampp\php\ext\php_xdebug.dll" とします)。
-
次に、php.ini ファイルを編集し、
zend_extension=xdebug
の行を追加します。 この際、zend_extension=opcache
の行より下に追加するようにしてください。php.inizend_extension=xdebug
-
最後にWebサーバーを再起動します。
インストールできたか確認する
Xdebug がインストールできたら、phpinfo()
に Xdebug の情報が追加で表示されていますので確認してみましょう。
xdebug_info() 関数
ちなみに、Xdebug がインストールされると、Xdebug の情報を表示する関数、xdebug_info()
も使用できるようになっています。
phpinfo()
にも同様の内容が表示されていますが、phpinfo()
には他の情報も大量に表示されていますので、
Xdebug だけの情報が知りたい場合は xdebug_info()
の方が見やすいと思います。
モード
Xdebug ではいろんな機能が使用できますが、それらの機能は全て有効になっているわけではありません。
各機能は、それぞれ有効/無効を切り替えることができます。
つまり、使いたい機能がある場合は、その機能を個別に有効化する必要があります。
機能ごとの有効/無効(モード)は、php.ini で、xdebug.mode
という設定項目で変更できます。
複数の機能を同時に有効にしたい場合はカンマ区切りで指定します。
php.ini を変更した場合は、Webサーバーの再起動が必要ですので注意してください。
値 | 説明 |
---|---|
off | 全ての機能を無効にする |
debug | 「ステップ実行」機能を有効にする |
develop | 「開発ヘルパー」機能を有効にする |
trace | 「関数トレース」機能を有効にする |
profile | 「プロファイリング」機能を有効にする |
gcstats | 「ガベージコレクション統計」機能を有効にする |
coverage | 「コードカバレッジ解析」機能を有効にする |
[xdebug] xdebug.mode=develop,debug
どの機能が有効になっているか確認する
どの機能が有効になっているかは、phpinfo()
や xdebug_info()
を表示した際に、「Enabled Features」欄に表示されているので、そこでも確認できます。
開始タイミング
Xdebug では、いろいろな機能がありますが、それらはすべてのHTTPリクエスト時に常に開始されるようにはなっていません。 全ての機能がすべてのHTTPリクエストで開始されているとパーフォーマンスの観点からあまりよろしくないからです。 必要なタイミングで必要なものだけ開始するという設定になっているのです。
どの機能がどのタイミングで開始するかは xdebug.start_with_request
で設定できます。
しかしながら、機能ごとに細かく設定できるわけではなく、Xdebug 全体の設定になりますので、変更すると全ての機能の開始タイミングに影響が出ます。
設定できる値は下記の4つです。思ったタイミングで動かなかったり、動いてしまったりする場合は、この値を確認してください。
-
yes
:全てのHTTPリクエストで開始する -
no
:全てのHTTPリクエストで開始しない -
trigger
:条件を満たしたHTTPリクエスト(トリガー)でのみ開始する -
default
:各機能ごとに異なったデフォルト設定とする機能 デフォルト設定 ステップ実行 trigger
開発ヘルパー (影響なし) 関数トレース trigger
プロファイリング yes
ガベージコレクション統計 no
コードカバレッジ解析 (影響なし)
例えば、上記のデフォルト設定(xdebug.start_with_request=default
)だと、「プロファイリング」機能は全てのHTTPリクエストで開始され、
「ステップ実行」「関数トレース」機能は条件を満たしたHTTPリクエストが送信されたときだけ開始され、
「ガベージコレクション統計」機能はHTTPリクエストでは開始されないので、関数を自分で呼び出すなど、別の方法で開始する必要がある、ということです。
条件を満たしたHTTPリクエスト(トリガー)
条件を満たしたHTTPリクエストの場合のみ開始される設定がトリガーです。
トリガーの条件は、$_ENV
、$_GET
、$_POST
、$_COOKIE
のいずれかに XDEBUG_TRIGGER
という名前の値があることです。
古いバージョンの Xdebug では、XDEBUG_TRIGGER
の代わりに、
XDEBUG_SESSION
(ステップ実行用)、XDEBUG_PROFILE
(プロファイリング用)、XDEBUG_TRACE
(関数トレース用)が使用されていたため、
互換性のためそれらも使用することができるようです。
GETパラメーターをトリガーにする
GETパラメーター($_GET
)でトリガーさせる方法は簡単です。
URLのGETパラメーターとして XDEBUG_TRIGGER
を付けて、Webブラウザからアクセスするだけです。
GETパラメーターが1つ以上ある場合は、?
ではなく &
で繋ぎます。
https://example.com/hoge/hoge?XDEBUG_TRIGGER
Cookie をトリガーにする
GETパラメーターをトリガーにする方法は簡単ではありますが、画面遷移が必要な場合や Ajax などを使用している場合は難しくなってきます。
リンクやボタンをクリックするたびに必要になるのですから、それは面倒になってくると思います。
しばらくの間、続けてトリガーさせるためには、Cookie($_COOKIE
)からトリガーさせた方が楽です。
そのためのWebブラウザの拡張機能がありますので、それを使うと便利です。
ステップ実行(モード:debug)
この機能は、PHP スクリプトの実行中に IDE またはエディターでコードをステップ実行ができるようになるものです。 PHP スクリプトを1行ずつ実行したり、実行中に一時停止させて、その時点の変数の内容を確認したりといったようなことができます。 PHP はWebサーバー上で動作していて、WebブラウザとはHTTPで通信しているため、ステップ実行は難しいのですが、それを可能にしてくれます。 PHP の IDE やエディターはいろいろありますが、ここでは Visual Studio Code(以下、VS Code)を使った方法を紹介します。
VS Code の設定
VS Code の設定で必要なことは下記の2つです。
拡張機能「PHP Debug」をインストール
Xdebug はWebサーバー上で動いていますので、VS Code は通信を行う必要があります。 そのため、VS Code に拡張機能を追加する必要があります。この拡張機能が Xdebug と通信してくれます。 Xdebug の公式でオススメされてるのは Felix Becker さんの「PHP Debug」という拡張機能です。 拡張機能の検索欄に「php debug」と入力して検索しインストールします。 同じ名前の拡張機能がたくさんあるので間違えないよう注意です。
launch.json を作成する
launch.json が無い場合は作成します。無い場合は自動で作ってくれます。
手動で編集する場合は、下記の内容にします。 プルダウンの「構成の追加」から「PHP: Listen for Xdebug」を選択して追加したのと同じ内容です。
{ // IntelliSense を使用して利用可能な属性を学べます。 // 既存の属性の説明をホバーして表示します。 // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Listen for Xdebug", "type": "php", "request": "launch", "port": 9003 } ] }
Xdebug の設定
VS Code の拡張機能「PHP Debug」のドキュメントには、xdebug.start_with_request
を yes
とし、全てのHTTPリクエストで開始するよう Xdebug を設定すると記載されていますが、これは必須ではありません。
yes
としてしまうと、ステップ実行機能以外の他の機能の開始タイミングにまで影響が出てしまうので注意してください(他の機能を使わないということであれば yes
で問題はありません)。
ステップ実行機能の開始タイミングはデフォルトではトリガーです。
ステップ実行時のHTTPリクエストでトリガーできてれば良いだけです。
ブラウザに Xdebug の拡張機能を入れている場合は、Cookie でトリガーさせるのは簡単にできると思いますので、xdebug.start_with_request
は default
のままで問題ありません。
本当に必要なことは、モードを有効にすることだけです。
[xdebug] xdebug.mode=debug
あまり他の機能を使わず、ブラウザに Xdebug の拡張機能を入れるのが面倒で、常にステップ実行できる状態としたいのであれば、xdebug.start_with_request
を yes
としても問題ありません。
用途に合わせて設定しましょう。
[xdebug] xdebug.mode=debug xdebug.start_with_request=yes
ステップ実行を行う
準備できたので実際にやってみます。 流れは下記になります。
- VS Code で、一時停止させたい個所にブレークポイントを付ける
- VS Code で、デバッグを開始(F5)する。その際、launch.json に作成した「Listen for Xdebug」を使用する
- Webブラウザの Xdebug の拡張機能で、ステップ実行(Debug)のトリガーを有効にする
(xdebug.start_with_request
がyes
の場合は不要) - Webブラウザで、ブレークポイントを付けた個所のURLにアクセスする
開発ヘルパー(モード:develop)
この機能は、PHP の組み込み関数を拡張し、より多くの情報を取得できるようになるものです。 具体的には、下記の3つが有効になります。
var_dump()
関数の拡張- Notice、Warning、Error、例外発生時にスタックトレース表示
- PHP の動作を微調整するための多数の関数と設定
var_dump() 関数の拡張
PHP の組み込み var_dump()
関数の出力がHTML形式に変更され色が付くようになります。
また、呼び出し場所のファイル名と行番号が含まれるようになります。
C:\Users\Test\develop.php:22: array (size=4) 'one' => string 'a somewhat long string!' (length=23) 'two' => array (size=2) 1 => int 1 2 => int 2 'three' => array (size=1) 'foo' => string 'bar' (length=3) 'four' => object(Test)[1] public 'pub' => boolean false private 'priv' => boolean true protected 'prot' => int 42
表示/非表示の出力量の設定
拡張された var_dump()
関数の出力はHTML形式にはなりますが、それに伴って出力される量に制限がかかるようになります。
例えば、長すぎる文字列や、長すぎたり、深すぎたりする配列やオブジェクトは、省略記号 "…" で省略されるようになります。
これは、メモリ不足に陥らないための措置ではありますが、見たいと思っていた個所の値が見れなくなってしまうという欠点があります。
デフォルト値のままだとかなり困ると思いますので、メモリ不足に陥らない範囲で調整しましょう。
出力される量に関する設定は下記があります。
-
xdebug.var_display_max_data
文字列が切り捨てられ、省略記号 "…" で表示される前の文字列の長さを制御します。
デフォルトは 512、無制限は -1 です。 -
xdebug.var_display_max_children
表示される配列要素またはオブジェクトプロパティの数を制御します。
デフォルトは 128、無制限は -1 です。 -
xdebug.var_display_max_depth
データ構造情報の深さ(ネスト)の数を制御します。
デフォルトは 3、最大は 1023 で、-1 を指定すると最大 1023 と同じになります。
PHP_CodeSniffer を使っている場合、xdebug.var_display_max_children
と xdebug.var_display_max_depth
の両方を大きい値(もしくは -1)に設定すると、
PHP_CodeSniffer の処理速度がかなり遅くなってしまい、まともに使用できなくなってしまうので注意してください。
[xdebug] xdebug.mode=develop xdebug.var_display_max_data=512 xdebug.var_display_max_children=128 xdebug.var_display_max_depth=3
スタックトレースの表示
Notice、Warning、Error、例外発生時に、スタックトレースが表示されるようになります。 スタックトレースには、スクリプトの開始からエラーが発生した場所までの間に呼び出されたすべての関数とメソッドのリストが含まれています。
PHP の動作を微調整するための多数の関数と設定
開発ヘルパー機能が有効になっている場合のみ使える関数があります。 主にどこで関数が呼ばれているのか調べたり、処理時間を調べたり、メモリ使用量を調べたりするような関数です。 どんな関数や設定があるのかは、ここでは記載しません。 大量にありますので、英語ですが公式のドキュメントを見てもらった方が良いと思います。
関数トレース(モード:trace)
この機能は、すべての関数の呼び出しを追跡してファイルに保存できるというものです。 PHP アプリケーションの実行中に何が起こっているのかを正確に把握しようとしている場合に役立ちます。
TRACE START [2021-09-18 11:28:18.886632] 0.0064 365808 -> {main}() C:\Users\Test\trace.php:0 0.0064 365808 -> str_split($string = 'Xdebug') C:\Users\Test\trace.php:8 0.0200 366376 -> ret_ord($c = 'X') C:\Users\Test\trace.php:10 0.0202 366376 -> ord($character = 'X') C:\Users\Test\trace.php:5 0.0204 366376 -> ret_ord($c = 'd') C:\Users\Test\trace.php:10 0.0205 366376 -> ord($character = 'd') C:\Users\Test\trace.php:5 0.0207 366376 -> ret_ord($c = 'e') C:\Users\Test\trace.php:10 0.0208 366376 -> ord($character = 'e') C:\Users\Test\trace.php:5 0.0209 366376 -> ret_ord($c = 'b') C:\Users\Test\trace.php:10 0.0210 366376 -> ord($character = 'b') C:\Users\Test\trace.php:5 0.0211 366376 -> ret_ord($c = 'u') C:\Users\Test\trace.php:10 0.0211 366376 -> ord($character = 'u') C:\Users\Test\trace.php:5 0.0211 366376 -> ret_ord($c = 'g') C:\Users\Test\trace.php:10 0.0212 366376 -> ord($character = 'g') C:\Users\Test\trace.php:5 0.0215 282592 TRACE END [2021-09-18 11:28:18.901926]
関数トレースを開始する
関数トレースの開始タイミングは、デフォルトではトリガーに設定されているので、条件を満たしてあげる必要があります。
GETパラメーターからトリガーする場合は、URLのGETパラメーターに XDEBUG_TRIGGER
を付けて、Webブラウザからアクセスするだけです。
GETパラメーターが1つ以上ある場合は、?
ではなく &
で繋げます。
ブラウザに Xdebug の拡張機能を入れている場合は、そちらを使って Cookie からトリガーした方が便利です。
https://example.com/hoge/hoge?XDEBUG_TRIGGER
ファイルの出力先を指定する
トレースファイルの出力先のディレクトリは xdebug.output_dir
で指定できます。
デフォルトの場合は一時ディレクトリ("C:\Windows\Temp")になります。
出力ファイル名の形式は xdebug.trace_output_name
で指定できます。
デフォルトの場合は trace.%c
形式になります。%c
はCRC32のことです。
タイムスタンプ形式にするには %t
を使用します。
ファイルの拡張子は必ず .xt になり、変更できません。
[xdebug] xdebug.mode=trace xdebug.output_dir=C:\xampp\xdebug_output xdebug.trace_output_name=trace.%t
プロファイリング(モード:profile)
この機能は、PHP アプリケーションのパフォーマンスを分析し、ボトルネックを見つけるためのものです。 例えば、速度が遅いけど、どこが遅いのかわからないといった場合ですね。
この機能を有効にした状態でHTTPリクエストを送信すると、プロファイリング用のデータが cachegrind.out という形式のファイルとして出力されます。
その出力された cachegrind.out ファイルを、KCacheGrind 互換のビュアー(Windows の場合は QCacheGrind)で読み込めばボトルネックを探せます。
ファイルの出力先を指定する
cachegrind.out ファイルの出力先のディレクトリは xdebug.output_dir
で指定できます。
デフォルトの場合は一時ディレクトリ("C:\Windows\Temp")になります。
出力ファイル名の形式は xdebug.profiler_output_name
で指定できます。
デフォルトの場合は cachegrind.out.%p
形式になります。%p
はプロセスIDのことです。
タイムスタンプ形式にするには %t
を使用します。
[xdebug] xdebug.mode=profile xdebug.output_dir=C:\xampp\xdebug_output xdebug.profiler_output_name=cachegrind.out.%t
ガベージコレクション統計(モード:gcstats)
この機能は、PHP の内部ガベージコレクターがトリガーされるタイミング、クリーンアップできた変数の数、所要時間、実際に解放されたメモリの量を確認するためのものです。 PHP のガベージコレクション(GC)は、メモリとパフォーマンスに深刻な影響を与える可能性があるため、トリガーされるタイミングと各実行の効率を理解することで、プログラムを最適化できます。 ただし、このレベルの最適化をする必要はほとんどないとは思いますので、用途は限られるでしょう。
Garbage Collection Report version: 1 creator: xdebug 3.0.4 (PHP 8.0.4RC1) Collected | Efficiency% | Duration | Memory Before | Memory After | Reduction% | Function ----------+-------------+----------+---------------+--------------+------------+--------- 9965 | 99.65 % | 0.00 ms | 10293072 | 1125272 | 89.07 % | hoge 10000 | 100.00 % | 0.00 ms | 10325272 | 1125272 | 89.10 % | hoge 36 | 0.36 % | 0.00 ms | 1158168 | 1125048 | 2.86 % | gc_collect_cycles
ガベージコレクション統計を開始する
ガベージコレクション統計を開始するには、2つの方法があります。
コマンドオプションで指定する
1つ目の方法は、php
コマンドのオプションで指定する方法です。
主な使用例は、個々のCLIスクリプト実行の統計を収集することです。
php -dxdebug.mode=gcstats -dxdebug.start_with_request=yes your_script.php
関数を直接呼ぶ
2つ目の方法は、PHP スクリプトで xdebug_start_gcstats()
を直接呼び出して開始することです。
停止させる場合は、xdebug_stop_gcstats()
を呼び出します。
これにより、統計収集をいつ開始し、いつ停止するかをより細かく制御できます。
[xdebug] xdebug.mode=gcstats
<?php xdebug_start_gcstats(); // 調べたい処理 xdebug_stop_gcstats();
ファイルの出力先を指定する
統計ファイルの出力先のディレクトリは xdebug.output_dir
で指定できます。
デフォルトの場合は一時ディレクトリ("C:\Windows\Temp")になります。
出力ファイル名の形式は xdebug.gc_stats_output_name
で指定できます。
デフォルトの場合は gcstats.%p
形式になります。%p
はプロセスIDのことです。
タイムスタンプ形式にするには %t
を使用します。
[xdebug] xdebug.mode=gcstats xdebug.output_dir=C:\xampp\xdebug_output xdebug.gc_stats_output_name=gcstats.%t
コードカバレッジ解析(モード:coverage)
この機能は、PHPUnit でテストを実行したときに、テスト対象のコードのうちどれくらいの割合がテストされたかというのを調べるためのものです。 基本的には PHPUnit と組み合わせて使われるものです。 そのため、主に PHPUnit の機能の使い方の説明になってしまうので、詳しい使い方は「PHPUnit の使い方」を参考にしてください。 Xdebug でこの機能を有効にしておかないと、PHPUnit でコードカバレッジ解析はできません。
[xdebug] xdebug.mode=coverage
参考サイト
- Xdebug - Debugger and Profiler Tool for PHP
- Xdebug: Documentation » Step Debugging
- Xdebug: Documentation » Development Helpers
- Xdebug: Documentation » Function Trace
- Xdebug: Documentation » Profiling
- Xdebug: Documentation » Garbage Collection Statistics
- Xdebug: Documentation » Code Coverage Analysis
- 【PHP】Visual Studio Codeを使ってデバッグをする方法(xdebugを使用) - buralog