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 の遅さを調べるときは、次の順で進めると無駄が少なくなります。

  1. Query Monitor で全体を見る: データベースのクエリ数や時間、外部への HTTP リクエスト、フックの実行時間をまず確認します。原因がクエリや外部 API なら、ここで見つかることがほとんどです。
  2. Xdebug のプロファイルで PHP の処理を見る: Query Monitor で目立つ原因がなく、PHP の処理自体が重い場合にプロファイルを取ります。同じページで2〜3回取り、毎回上位に出る関数を探します。初回はキャッシュが温まっていないため、極端に遅く出ることがあります。
  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 を使う。
  • 作業後はモードを戻し、出力ファイルを削除する。本番には入れず、ステージングで再現させて調べる。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲