2026年6月16日
2026年6月16日
PHPのデバッグツール(Xdebug)の設定方法:プロファイラとトレースで遅い処理を見つける
Xdebug はブレークポイントで止めるステップ実行だけでなく、どの関数にどれだけ時間がかかったかを記録するプロファイラと、関数の呼び出し順をすべて書き出すトレースの機能も持っています。「WordPress の特定のページだけ遅い」「どのプラグインが重いのか分からない」といった場面では、こちらのほうが原因に早くたどり着けます。この記事では、Xdebug 3 の xdebug.mode の考え方、プロファイラとトレースの設定、出力ファイルの読み方、WordPress での調べ方、作業後の後片付けまでを説明します。インストールと VS Code でのステップ実行の設定は別記事で扱っているので、ここではそれ以外のモードに絞ります。
xdebug.modeで機能を切り替える
Xdebug 3 では、使う機能を xdebug.mode で選びます。主な値は次のとおりです。
- develop: エラー時のスタックトレースや
var_dump()の表示を見やすくします。 - debug: IDE と接続してステップ実行します。
- profile: 関数ごとの処理時間と呼び出し回数を記録します。
- trace: 関数の呼び出しを順番にファイルへ書き出します。
- coverage: PHPUnit などでコードカバレッジを取るときに使います。
- off: 何もしません。拡張は読み込まれていても、負荷はほとんどかかりません。
値はカンマ区切りで複数指定できます(例: develop,debug)。ただし profile と trace は処理を大きく遅くするため、普段は外しておき、調べるときだけ有効にするのが基本です。php.ini を書き換えずに、環境変数 XDEBUG_MODE で一時的にモードを上書きすることもできます。
# コマンドラインで1回だけプロファイルを取る
XDEBUG_MODE=profile php script.php
今どのモードが有効かは、php -v の出力に Xdebug が表示されるか、xdebug_info() を呼んだページで確認できます。xdebug_info() のページはサーバーの設定が見えるため、確認が終わったら削除します。
プロファイラを設定する
開発環境の php.ini(または Xdebug 用の設定ファイル)に次のように書きます。設定ファイルの場所は php --ini で確認できます。
[xdebug]
zend_extension=xdebug
xdebug.mode=profile
xdebug.start_with_request=trigger
xdebug.output_dir=/tmp/xdebug
xdebug.profiler_output_name=cachegrind.out.%t.%p
start_with_request=trigger にすると、すべてのリクエストではなく、トリガーを付けたリクエストだけを記録します。これを yes にすると、PHP が処理するすべてのリクエストでファイルが作られ、ディスクがすぐに埋まります。トリガーは、URL に XDEBUG_TRIGGER を付ける方法が簡単です。
https://local.example.test/sample-page/?XDEBUG_TRIGGER=1
同じ名前の Cookie を送っても記録されます。ブラウザの拡張機能でこの Cookie を付け外しできるものもあります。
output_dir のディレクトリは事前に作り、PHP の実行ユーザー(PHP-FPM なら www-data など)が書き込めるようにしておきます。書き込めないと、エラーにならずにファイルが作られないことがあるので、ファイルが出ないときはまずここを確認してください。%t はタイムスタンプ、%p はプロセス ID に置き換わります。
設定を変えたら、PHP-FPM や Web サーバーを再起動して反映します。
sudo systemctl restart php8.3-fpm # バージョンは環境に合わせて読み替え
プロファイルの読み方
作られた cachegrind.out.* ファイルは、テキストですが人が直接読む形式ではありません。次のようなツールで開きます。
- KCachegrind(Linux)、QCachegrind(Windows・macOS 向けのビルド)
- PhpStorm に付いているプロファイル結果の表示機能
- Webgrind(ブラウザで見るツール。開発用のマシンの中だけで使い、公開サーバーには置かない)
Xdebug の設定によってはファイルが gzip で圧縮され、末尾が .gz になります。ツールが読めない場合は gunzip で展開してから開いてください。
画面にはおおむね次の2つの数字が並びます。名前はツールによって違いますが、意味は同じです。
- Self(自身の時間): その関数の中だけで使った時間。ほかの関数を呼んだ時間は含みません。
- Inclusive(合計の時間): その関数から呼んだ関数も含めた時間。
まず Inclusive で並べ替えて、時間の大部分を占める流れを上から追い、次に Self で並べ替えて、その中で実際に時間を使っている関数を探します。WordPress では、上位に do_action や apply_filters が並ぶことが多いですが、これは「フックに登録された処理の合計」なので、その下に呼ばれている関数をたどり、どのプラグインやテーマのファイルにある関数かを確認します。
呼び出し回数も重要な手がかりです。1回の処理は速くても、ループの中で数千回呼ばれていれば、全体では大きな時間になります。データベースへの問い合わせを繰り返す関数や、ファイルを何度も読む関数がよく見つかります。
トレースで呼び出しの流れを追う
プロファイルが「どこに時間がかかったか」を示すのに対し、トレースは「どの順番で何が呼ばれたか」を示します。期待と違う処理が走っている、フックの実行順が分からない、といった場面で使います。
xdebug.mode=trace
xdebug.start_with_request=trigger
xdebug.output_dir=/tmp/xdebug
xdebug.trace_output_name=trace.%t.%p
xdebug.trace_format=0
trace_format=0 は人が読める形式です。ほかの形式は、解析用のツールに読ませるときに使います。トリガーの付け方はプロファイラと同じです。
トレースファイルは、WordPress の1ページ分でも数十万行になることがあります。テキストエディターで全部を読むのではなく、grep で目的のファイル名や関数名を探します。ファイルが圧縮されて末尾が .gz になっている場合は zgrep を使います。
grep -n "my-plugin/" /tmp/xdebug/trace.*.xt | head -50
特定の処理だけを記録したい場合は、コードの中で xdebug_start_trace() と xdebug_stop_trace() を呼び、その間だけを書き出すこともできます。この場合も xdebug.mode に trace を含めておく必要があります。
トレースには関数の引数も記録されるため、パスワードやメールアドレスなどの値がファイルに残る可能性があります。本番のデータを使った環境でトレースを取った場合は、調べ終わったらファイルを削除してください。
WordPressでの調べ方
WordPress の遅さを調べるときは、次の順で進めると無駄が少なくなります。
- Query Monitor で全体を見る: データベースのクエリ数や時間、外部への HTTP リクエスト、フックの実行時間をまず確認します。原因がクエリや外部 API なら、ここで見つかることがほとんどです。
- Xdebug のプロファイルで PHP の処理を見る: Query Monitor で目立つ原因がなく、PHP の処理自体が重い場合にプロファイルを取ります。同じページで2〜3回取り、毎回上位に出る関数を探します。初回はキャッシュが温まっていないため、極端に遅く出ることがあります。
- トレースで流れを確認する: プロファイルで見つけた関数が、なぜ、どこから呼ばれているのかが分からないときにトレースを使います。
@wordpress/env で開発環境を作っている場合は、起動時のオプションで Xdebug を有効にできます。対応しているモードや書き方は版によって異なるため、wp-env start --help で確認してください(2026年10月現在)。
プロファイル中の処理時間は、Xdebug の計測による上乗せで実際より長くなります。比べるべきなのは関数どうしの割合で、秒数そのものではありません。改善の効果は、Xdebug を off にした状態で、ページの表示時間を測って確かめます。
作業後の後片付けと本番環境
調べ終わったら、xdebug.mode を元の値(off や develop,debug など)に戻して再起動します。profile や trace を有効にしたままにすると、トリガーがなくても拡張の分だけ処理が重くなり、トリガーを知っている人がいればディスクを埋められる危険もあります。output_dir にたまったファイルも削除します。
本番サーバーに Xdebug を入れることは勧めません。本番で遅い原因を調べたい場合は、まず本番と同じデータと構成のステージング環境で再現させ、そこでプロファイルを取ります。本番での計測が欠かせない場合は、常時計測を前提に作られた APM(アプリケーション性能監視)のサービスを検討してください。ステージングに本番のデータベースを複製するときは、事前にバックアップを取り、メール送信や決済などの外部連携が動かないようにしておきます。
まとめ
- Xdebug 3 は
xdebug.modeで機能を選び、profile と trace は調べるときだけ有効にする。 start_with_request=triggerとXDEBUG_TRIGGERで、記録するリクエストを絞る。- プロファイルは KCachegrind などで開き、Inclusive で流れを追い、Self と呼び出し回数で重い関数を見つける。
- WordPress では Query Monitor で全体を見てから、PHP の処理が重い場合に Xdebug を使う。
- 作業後はモードを戻し、出力ファイルを削除する。本番には入れず、ステージングで再現させて調べる。