---
title: "Xdebugとは？PHPデバッグの使い方・インストール・php.ini設定・VSCode連携【3.5.3対応】"
url: "https://www.issoh.co.jp/tech/details/7515/"
published: 2025-07-01
updated: 2026-10-24
categories: ["PHP"]
publisher: "株式会社一創"
---

# Xdebugとは？PHPデバッグの使い方・インストール・php.ini設定・VSCode連携【3.5.3対応】

Xdebug（エックスデバッグ）は、PHPにステップ実行・プロファイル・コードカバレッジなどを追加する拡張モジュールです。開発者はPHPコア開発者のDerick Rethans氏で、2026年10月時点の最新安定版は2026年6月8日公開の3.5.3です（[公式のダウンロードページ](https://xdebug.org/download)で確認できます）。次の3.6は9月8日に3.6.0alpha1が出た段階です。本記事では、Xdebug 3.5.3と3.6.0alpha1をPHP 8.5.8（macOS・Homebrew）に読み込んだ実機の出力をもとに、インストールからphp.iniの設定、VS Code・PhpStorm・Dockerでの接続までを解説します。「localhost:9003に接続できない」ときの切り分けと、本番環境に入れてはいけない理由を示す実測値も扱います。

## まとめ：Xdebug 3の導入と設定の要点

- Xdebugは `xdebug.mode` で機能を選ぶ拡張モジュール。ステップ実行は `debug`、性能計測は `profile`、カバレッジは `coverage`。既定値は `develop`。
- インストールの第一推奨はPIE（`pie install xdebug/xdebug`）。PECLとWindows向けウィザードは、公式ドキュメント上「レガシーな導入方法」の扱い。
- Xdebug 3の既定ポートは9003。9000番を使う場合は `xdebug.client_port=9000` と指定する。`remote_enable` などの旧設定名は使えない。3.5.3では警告が出るが、3.6.0alpha1では警告も出ずに無視される。
- 普段は `start_with_request=trigger` にし、ブラウザ拡張・Cookie・`xdebug_break()` で止めたいリクエストだけデバッグする。
- 接続できないときは `xdebug.log` を出す。どのホストとポートに接続を試みたかがログに1行で出る。
- Xdebugを読み込むだけで既定の `develop` が有効になり、実測で約1.5倍遅くなった。本番環境には入れない。

## Xdebugでできること：7つのモードと役割

Xdebug 3では、機能ごとの有効化スイッチが `xdebug.mode` の1項目に統合されました。値はカンマ区切りで複数指定できます（例：`debug,develop`）。

| mode        | 有効になる機能        | 主な用途                    |
| ----------- | -------------- | ----------------------- |
| off         | なし             | 負荷をほぼゼロにする              |
| develop（既定） | 開発ヘルパー         | var\_dump()の整形・エラー表示の強化 |
| debug       | ステップ実行         | IDEでブレークポイントを使う         |
| profile     | プロファイラ         | ボトルネックの特定               |
| trace       | 関数トレース・フレームグラフ | 呼び出しの全記録                |
| coverage    | コードカバレッジ       | PHPUnit・Pestの網羅率計測      |
| gcstats     | GC統計           | ガベージコレクションの調査           |

`var_dump()` や `error_log()` を挟むデバッグとの違いは、コードを書き換えずに実行を止められる点です。ブレークポイントで止めた時点の変数とコールスタックをIDEで確認し、ステップイン（関数の中へ入る）・ステップオーバー（関数を1行として進める）・ステップアウト（呼び出し元へ戻る）で1行ずつ進めます。ループの途中で値が変わる不具合のように、出力を仕込む位置を何度も変えることになる調査で差が出ます。逆に、1つの変数の値を1回見れば済む場面では、Laravelの `dd()` や `var_dump()` の方が早く終わります。IDEの待ち受けとトリガーの準備が要らないためです。

`develop` モードには無限再帰の保護も含まれます。関数の呼び出しが `xdebug.max_nesting_level`（既定512）に達すると、`Xdebug has detected a possible infinite loop, and aborted your script with a stack depth of '512' frames` というメッセージのError例外が投げられ、捕捉しなければ処理が停止します。意図した再帰であることと終了条件を確認したうえで、必要な場合に限ってこの値を引き上げます。

## Xdebugのインストール手順：PIE・パッケージ・PECL・Windows

### PIEでのインストール（公式の第一推奨）

公式のインストール手順は、PHP拡張のインストーラーPIE（2026年10月21日に1.5.3を公開）を主な手段としています。PIEの導入後は、macOS・Linux・Windowsのいずれでも次のコマンドを使えます。macOSでは `brew install pie` でPIEを導入できます。LinuxとWindowsでは、先に[PIEの公式リポジトリ](https://github.com/php/pie)の導入手順を済ませます。

```
pie install xdebug/xdebug
```

macOSとLinuxではソースを取得してビルドし、Windowsでは公開済みのDLLを取得します。いずれの場合もPIEが読み込み用のINIファイルの作成まで試みます。

### Linuxのパッケージマネージャでのインストール

パッケージで入れるのが最も手早い方法です。

```
# Debian / Ubuntu
sudo apt-get install php-xdebug
# Arch Linux
sudo pacman -S xdebug
# Fedora
sudo dnf install php-xdebug
```

ただしディストリビューションのパッケージは古い版のことがあります。公式は、サポート切れの版が入る場合はPIEかソースビルドへ切り替えるよう案内しています。

### PECLとWindowsのインストールウィザード（レガシー扱い）

`pecl install xdebug` は現在も使えますが、公式ドキュメントではレガシーな導入方法に分類されました。PECLを使う場合、php.iniへ `extension=xdebug.so` を追記するよう促す表示は無視します。Xdebugは `zend_extension` で読み込む必要があるためです。

Windowsで手動導入する場合は、xdebug.orgのインストールウィザード（xdebug.org/wizard）に `php -i` の出力を貼り付けると、PHPのバージョン・スレッドセーフ有無・アーキテクチャに合うDLL（`php_xdebug.dll`）と配置先の `ext` ディレクトリが提示されます。DLLの選択を誤ると読み込みに失敗するため、手動で選ぶよりウィザードかPIEが確実です。

### 対応するPHPバージョン

| Xdebug | 対応PHP   | 状態（2026年10月）      |
| ------ | ------- | ----------------- |
| 3.6    | 8.2〜8.6 | 3.6.0alpha1（9月8日） |
| 3.5    | 8.1〜8.5 | 最新安定版3.5.3        |
| 3.4    | 8.0〜8.4 | 旧版                |
| 2.x    | 7.x以前   | サポート終了            |

表は[公式の互換表](https://xdebug.org/docs/compat)に基づきます。[PHP 8.5](/tech/details/8179/)を使うならXdebug 3.5以上が必要です。3.5.3のパッケージ定義では、PHPの対応上限が8.5.99に設定されています。[3.6.0alpha1の変更履歴](https://xdebug.org/updates)には、PHP 8.6への対応と並んでPHP 8.0・8.1のサポート終了が載っています。FrankenPHPのワーカーモードで、リクエストごとにデバッガーを初期化し直す修正（#2403）もこの版からです。

### php -vとxdebug\_info()での確認

読み込めていれば、`php -v` の出力に `with Xdebug` の行が加わります。

```
$ php -v
PHP 8.5.8 (cli) (built: Jul  1 2026 03:46:27) (NTS)
Copyright (c) The PHP Group
Built by Homebrew
Zend Engine v4.5.8, Copyright (c) Zend Technologies
    with Xdebug v3.5.3, Copyright (c) 2002-2026, by Derick Rethans
    with Zend OPcache v8.5.8, Copyright (c), by Zend Technologies
```

どの機能が有効かは `php -r 'xdebug_info();'` で確認します。「Enabled Features」欄に、Step Debugger・Profilerなどの有効／無効が一覧で出ます。Webサーバー経由の設定を確かめるときは、`xdebug_info()` を呼ぶPHPファイルをブラウザで開きます。CLIとPHP-FPMは別のphp.iniを読むことがあるため、両方で確認します。

## php.iniの設定：xdebug.modeとstart\_with\_request

### ステップ実行のための最小構成

同じマシン上のIDEに接続する最小設定は次の3行で、`conf.d` 配下の `99-xdebug.ini` などに書きます。PIEなどがすでに読み込み設定を作成している場合は、`zend_extension` を重複して追加せず、その設定ファイルを編集します。

```
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=trigger
; 既定値のままなら不要（client_host=localhost / client_port=9003）
```

各設定の定義と既定値は[公式の設定一覧](https://xdebug.org/docs/all%5Fsettings)にまとまっています。`xdebug.mode` はPHPプロセスの起動時にしか読まれません。`.htaccess`・`.user.ini`・Apacheの `php_admin_value` では設定できないため、php.iniを変えたらPHP-FPMやApacheを再起動します。

### start\_with\_requestの4つの値と使い分け

| 値           | 動作                             |
| ----------- | ------------------------------ |
| yes         | 毎回のリクエスト開始時に起動                 |
| trigger     | トリガーがあるときだけ起動                  |
| no          | 開始時は起動しない                      |
| default（既定） | debugはtrigger、profileはyesとして動く |

`yes` はIDEが待ち受けていないとリクエストのたびに接続を試みます。実機では、IDEを起動していない状態で `yes` にすると、スクリプトの実行ごとに接続失敗の警告が出ました。普段は `trigger` にし、止めたいリクエストだけトリガーを付ける運用を勧めます。

トリガー名は `XDEBUG_TRIGGER` で、環境変数・GET・POST・Cookieのどれで渡しても有効です。ステップ実行では旧名の `XDEBUG_SESSION` も使えます。

```
# CLIで1回だけデバッグする
XDEBUG_TRIGGER=1 php artisan migrate
# ブラウザからはクエリで渡す
https://localhost/index.php?XDEBUG_TRIGGER=1
```

実機でも、同じ設定のまま `XDEBUG_TRIGGER` を付けない実行は待ち受け側に接続せず、付けた実行だけが接続しました。

### ブラウザ拡張・Cookieによるトリガーの設定

ブラウザから毎回クエリを付けるのは手間なので、Cookieを付けるブラウザ拡張を使います。[公式のステップ実行の解説](https://xdebug.org/docs/step%5Fdebug)が挙げている拡張は次のとおりです。

- Firefox・Chrome（Chromium系を含む）：Xdebug Helper by JetBrains
- Edge：Xdebug Helper
- Safari：XDebugToggle

拡張のアイコンからデバッグを選ぶと、そのサイトへのリクエストに `XDEBUG_SESSION` というCookieが付きます。拡張を入れずに同じ状態を作るなら、URLに `XDEBUG_SESSION_START` を付けて1回開きます。PHPのビルトインサーバーで確かめると、Xdebug 3.5.3は次のCookieを返しました。

```
GET /index.php?XDEBUG_SESSION_START=1
Set-Cookie: XDEBUG_SESSION=1; path=/; SameSite=Lax

GET /index.php?XDEBUG_SESSION_STOP=1
Set-Cookie: XDEBUG_SESSION=deleted; expires=Thu, 01 Jan 1970 00:00:01 GMT; Max-Age=0; path=/; SameSite=Lax
```

Cookieに有効期限は付いていません（3.1より前は1時間）。Cookieが残っている間は、PHPを通る画像やfaviconのリクエストまで毎回デバッグが始まります。調べ終えたら `XDEBUG_SESSION_STOP` を付けて開くか、拡張のアイコンでデバッグを無効に戻します。

### エラー発生時・任意の行からのデバッグ開始

トリガーを付けずにデバッグを始める方法が2つあります。`xdebug.mode=debug` のまま `xdebug.start_upon_error=yes` にすると、NoticeやWarningの発生時、または例外（Throwable）が投げられた時点でIDEへ接続します。この設定は `start_with_request` と独立しています。PhpStormのドキュメントが「Just-In-Timeモード」と呼んでいる使い方がこれです。実機でも、未定義の配列キーを読むWarningの時点で待ち受け側に接続しました。

もう1つはコードに `xdebug_break();` を書く方法です。`start_with_request=trigger` でまだデバッグが始まっていなければ、その行で接続を試み、IDEのブレークポイントと同じ位置で止まります。IDEが待ち受けていなかった実機の実行では、接続失敗の警告の後に `false` が返り、処理はそのまま続きました。

### XDEBUG\_MODE環境変数によるモードの一時切り替え

環境変数 `XDEBUG_MODE` は、php.iniの `xdebug.mode` より優先されます。普段はphp.iniを `off` にしておき、カバレッジ計測のときだけ `XDEBUG_MODE=coverage vendor/bin/phpunit` のように起動する使い方ができます。PHP-FPMは既定の `clear_env=yes` で環境変数を渡さないため、FPM経由で使う場合は、プール設定の `env[XDEBUG_MODE] = $XDEBUG_MODE` で必要な変数を明示的に渡すか、`clear_env` を無効にして環境変数を引き継ぎます。

## Xdebug 2からの設定移行：旧設定名の対応表

Xdebug 3では `xdebug.remote_*` 系の設定がすべて廃止・改名されました。古い記事の設定を書き写すと動きません。

| Xdebug 2の設定                 | Xdebug 3での書き方                       |
| --------------------------- | ----------------------------------- |
| remote\_enable=1            | mode=debug                          |
| remote\_autostart=1         | mode=debug＋start\_with\_request=yes |
| remote\_port=9000           | client\_port（既定9003）                |
| remote\_host                | client\_host                        |
| remote\_connect\_back       | discover\_client\_host              |
| remote\_log                 | log                                 |
| profiler\_enable=1          | mode=profile                        |
| profiler\_output\_dir       | output\_dir                         |
| 環境変数XDEBUG\_CONFIG=idekey=… | XDEBUG\_SESSION                     |

旧設定名を残したまま起動すると、Xdebug 3.5.3では次の警告が出ます（実機の出力）。

```
Xdebug: [Config] The setting 'xdebug.remote_enable' has been renamed, see the upgrading guide at https://xdebug.org/docs/upgrade_guide#changed-xdebug.remote_enable (See: https://xdebug.org/docs/errors#CFG-C-CHANGED)
```

この警告が出ても処理は続行されますが、旧設定は無視されます。実機でも `remote_enable` を指定した実行は、警告の後に既定の `localhost:9003` へ接続を試みました。

3.6からは、この警告も出なくなります。3.6.0alpha1の変更履歴には、Xdebug 2の改名・廃止済み設定のINI項目を削除する変更（#2387）が入っています。同じ `-d xdebug.remote_enable=1 -d xdebug.remote_port=9000` を付けて比べた結果は次のとおりです。

| 版           | 起動時の表示             | ini\_get(“xdebug.remote\_enable”) |
| ----------- | ------------------ | --------------------------------- |
| 3.5.3       | CFG-C-CHANGEDの警告2行 | 改名を知らせる文字列                        |
| 3.6.0alpha1 | 何も出ない              | false（項目なし）                       |

どちらの版も `client_port` は9003のままでした。3.6に上げた後は、古い設定が残っていても気付く手掛かりがありません。上げる前に3.5で警告が出ないことを確かめ、php.iniとconf.d配下から `remote_` で始まる行を消しておきます。

## VS Code・PhpStormでXdebugのステップ実行を使う手順

### VS Code（PHP Debug拡張）の設定

VS Codeでは拡張機能「PHP Debug」（識別子 `xdebug.php-debug`、2026年9月18日公開のv1.40.2）を入れます。`.vscode/launch.json` に次の構成を置き、実行とデバッグパネルで「Listen for Xdebug」を開始すると、VS Codeがポート9003で待ち受けます。

```
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9003
    }
  ]
}
```

行番号の左をクリックしてブレークポイントを置き、トリガー付きでページを開くと、その行で実行が止まります。止まらないときは次の順に確認します。

- `xdebug_info()` で Step Debugger が enabled になっているか
- ブレークポイントを置いたファイルが、実際に実行されているファイルと同じか（Dockerやリモートではパスが食い違う）
- リクエストにトリガーが付いているか（`start_with_request=trigger` の場合）

### PhpStormの設定

PhpStormも同じDBGpプロトコルで接続を受けるため、php.ini側の設定はVS Codeと共通です。IDE側では[PhpStormのXdebug構成ガイド](https://www.jetbrains.com/ja-jp/help/phpstorm/configuring-xdebug.html)に沿って、設定画面（`Ctrl+Alt+S`）の次の2か所を確認します。

- 「PHP」：CLIインタープリターの欄で選んだPHPに、Xdebugが読み込まれていると表示されるか
- 「PHP」→「デバッグ」：Debug portが `9003,9000`（既定）になっているか。コンテナやリモートのPHPから接続を受けるなら「外部接続を受け入れ可能」をオンにする

設定後は、メインメニューの「Run」→「Start Listening for PHP Debug Connections」（英語UIの表記）か、ツールバーの切り替えボタンで待ち受けを開始します。既定のDebug portは9003と9000で、Xdebug 3の既定接続と、Xdebug 2が稼働する環境からの接続を受けられます。同じ「デバッグ」ページの「パスマッピングが指定されていないときに最初の行で強制的にブレークする」をオンにしておくと、パスの対応付けが無いファイルに到達した時点で最初の行で止まり、「サーバー」ページでのマッピング設定へ誘導されます。DockerでVS Codeの `pathMappings` に当たる設定がこれです。エディタの補完やリファクタリングなど、デバッグ以外の機能は[PhpStormの入力支援機能の解説](/tech/details/7762/)で扱っています。

## DockerでXdebugを使う設定

コンテナ内のPHPから見ると `localhost` はコンテナ自身です。ホストのIDEへ接続するには `client_host` をホストに向け、ファイルのパスをIDE側と対応付けます。公式PHPイメージではPECLで導入します。Dockerのドキュメントは、互換性を固定するため版番号を明記するよう推奨しています。

```
# Dockerfile
FROM php:8.5-apache
RUN pecl install xdebug-3.5.3 \
 && docker-php-ext-enable xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/99-xdebug.ini
```

```
; xdebug.ini
xdebug.mode=debug
xdebug.start_with_request=trigger
xdebug.client_host=host.docker.internal
```

Docker DesktopではMacとWindowsで `host.docker.internal` が最初から解決できます。Linux上のDocker Engineでは解決されないため、Composeで `host-gateway` を割り当てます。

```
# compose.yaml
services:
  app:
    build: .
    volumes:
      - ./:/var/www/html
    extra_hosts:
      - "host.docker.internal:host-gateway"
```

VS Code側の `launch.json` の「Listen for Xdebug」構成内に、次の `pathMappings` を追加します。既存の `"port": 9003` の行末にカンマを付け、その直後に挿入してください。実行側とIDE側でパスが異なり、ほかの仕組みでも対応付けていない場合は、この設定がないとブレークポイントで止まりません。

```
"pathMappings": {
  "/var/www/html": "${workspaceFolder}"
}
```

WindowsでWSL2上のDockerを使う場合は、[WSLで開発環境を構築する手順](/tech/details/17354/)で扱う.wslconfigとDocker連携の設定もあわせて確認します。コンテナを使わない選択肢としては[Laravel Herd](/tech/details/17145/)があります。[HerdのXdebugのドキュメント](https://herd.laravel.com/docs/macos/debugging/xdebug)によると、無料版にもPHPのバージョン別にXdebugの拡張ファイルが同梱されており、php.iniへ手動で追記して有効にします。

## 「localhost:9003に接続できない」ときの切り分け

IDEが待ち受けていない状態でステップ実行を始めると、Xdebug 3.5.3は次のメッセージを出します（実機の出力）。

```
Xdebug: [Step Debug] Could not connect to debugging client. Tried: localhost:9003 (through xdebug.client_host/xdebug.client_port).
```

「Tried:」の後ろが、実際に接続を試みたホストとポートです。ここが想定と違えば設定の問題、合っていればIDE側かネットワークの問題です。

| Tried: の内容                | 原因                       | 対処                                |
| ------------------------- | ------------------------ | --------------------------------- |
| localhost:9000            | client\_portなどで9000を明示指定 | client\_portを9003へ                |
| localhost:9003（コンテナ内）     | 接続先がコンテナ自身               | client\_host=host.docker.internal |
| host.docker.internal:9003 | Linuxで名前解決できない           | extra\_hostsにhost-gateway         |
| 正しいホスト:9003               | IDEが待ち受けていない・通信遮断        | IDEの待ち受けと通信経路を確認                  |

より詳しく追うには `xdebug.log` にログファイルの絶対パスを指定します。

```
xdebug.log=/tmp/xdebug.log
xdebug.log_level=7
```

実機で接続に失敗したときのログは次のとおりでした。`INFO` で接続先、`ERR` で失敗の結論が記録されます。

```
[72824] Log opened at 2026-09-28 19:15:21.666284
[72824] [Step Debug] INFO: Connecting to configured address/port: localhost:9003.
[72824] [Step Debug] WARN: Creating socket for 'localhost:9003', poll success, but error: Operation now in progress (19).
[72824] [Step Debug] ERR: Could not connect to debugging client. Tried: localhost:9003 (through xdebug.client_host/xdebug.client_port).
[72824] Log closed at 2026-09-28 19:15:21.670084
```

`xdebug.log_level` の既定は7です。値ごとの記録範囲は次のとおりです。

| 値     | 名前            | 記録される内容     |
| ----- | ------------- | ----------- |
| 0     | Criticals     | 設定の誤り       |
| 1     | Errors        | 接続エラー       |
| 3     | Warnings      | 接続時の警告      |
| 5     | Communication | プロトコルのやり取り  |
| 7（既定） | Information   | 接続中の情報      |
| 10    | Debug         | ブレークポイントの解決 |

ブレークポイントで止まらない原因を調べるときは、10にするとIDEから送られたパスとファイルの対応付けが記録されます。

接続に成功すると、Xdebugは最初に `init` というXMLをIDEへ送ります。実機で受け取った内容の一部です。

```
<init xmlns="urn:debugger_protocol_v1" fileuri="file:///private/tmp/xdbg/t.php" language="PHP" xdebug:language_version="8.5.8" protocol_version="1.0" appid="72862" idekey="1"><engine version="3.5.3"><![CDATA[Xdebug]]></engine>...</init>
```

`fileuri` がPHP側で実行されたファイルのパスです。IDE上のパスと食い違う場合は、`pathMappings` の設定内容と、対応先に同じソースがあるかを確認します。

## プロファイルの出力先と解析ツール

`xdebug.mode=profile` で実行すると、`xdebug.output_dir`（公式の既定は `/tmp`）にCachegrind形式のファイルが出力されます。3.1以降のGZip対応ビルドでは既定でgzip圧縮されるため、実機ではファイル名が `cachegrind.out.73106.gz` になりました（数字はプロセスID）。KCacheGrindやPhpStormで開き、関数ごとの所要時間と呼び出し回数を確認します。QCacheGrindではgzipファイルを展開してから開くか、計測前に `xdebug.use_compression=0` を指定します。

Webリクエストでは `start_with_request=default` のままだとprofileは毎回起動します。ただし既定の出力名はプロセスID単位なので、同じワーカーの次のリクエストで上書きされる場合があります。計測したいリクエストだけに絞るなら `trigger` にします。本番のように常時計測したい場合は、Xdebugではなく[継続的プロファイリング](/tech/details/15709/)の仕組みを使います。

## 本番環境にXdebugを入れない理由：オーバーヘッドの実測

Xdebugは開発専用の拡張です。インストールしただけで既定の `develop` モードが有効になり、PHPの実行が遅くなります。5,000,000回のループ（文字列変換と `strlen()`）を、モードを変えて2回ずつ計測しました。

| 条件               | 1回目     | 2回目     |
| ---------------- | ------- | ------- |
| Xdebugを読み込まない    | 639ms   | 648ms   |
| mode=off         | 630ms   | 645ms   |
| mode=develop（既定） | 999ms   | 998ms   |
| mode=debug（接続なし） | 1,049ms | 1,086ms |

計測環境はmacOS（Intel）、PHP 8.5.8 NTS（OPcacheはCLIで無効の既定のまま）、Xdebug 3.5.3、`start_with_request=no` です。`off` は読み込まない場合と差が出ませんでした。`develop` と `debug` は約1.5〜1.7倍で、`debug` はIDEに接続していなくても遅くなりました。短いループ1種類の比較なので、アプリケーション全体の低下率はこれと異なります。計測に使ったコードとコマンドは次のとおりです。コマンドは、php.iniと追加のINIファイルでXdebugを読み込んでおらず、環境変数 `XDEBUG_MODE` も未設定の状態を前提にしています（`php --ini` と `php -v` で確かめられます）。

```
<?php // bench.php
$t = hrtime(true);
$s = 0;
for ($i = 0; $i < 5000000; $i++) { $s += strlen((string)$i); }
printf("%.0f ms\n", (hrtime(true) - $t) / 1e6);
```

```
php bench.php
php -d zend_extension=xdebug -d xdebug.mode=off -d xdebug.start_with_request=no bench.php
php -d zend_extension=xdebug -d xdebug.mode=develop -d xdebug.start_with_request=no bench.php
php -d zend_extension=xdebug -d xdebug.mode=debug -d xdebug.start_with_request=no bench.php
```

この結果から、判断は2つに分かれます。

- 本番サーバー：パッケージごとインストールしない。今回の計測では `off` に差は出なかったが、php.iniの1行か環境変数1つでデバッグ機能が有効になる状態が残る。
- 開発環境：php.iniは `off` にしておき、使うときだけ `XDEBUG_MODE` で有効にする。常時 `debug` にするとテストやComposerの実行も遅くなる。

開発用と本番用でPHPの拡張構成を分けておくことは、PHPで業務システムを[フルスクラッチ開発](/service/system/fullscratch/)するときの環境設計にも含まれます。

行カバレッジの計測だけが目的なら、カバレッジ専用の拡張PCOVも選べます。分岐・パスカバレッジが必要な場合はXdebugを使います。PHPUnitと[PestPHP](/tech/details/7255/)のカバレッジは、XdebugとPCOVのどちらのドライバでも取得できます。

## Xdebugに関するよくある質問

### Xdebugの読み方は何ですか？

「エックスデバッグ」と読みます。PHPのデバッグ用拡張モジュールで、Derick Rethans氏が開発しています。

### Xdebugは無料で使えますか？

無料で使えます。ライセンスはPHP License 3.0を基にしたXdebug License 1.03です。`xdebug_info()` の出力には、PatreonやGitHubを通じた開発支援の案内が表示されます。

### XdebugをPECLでインストールしてもよいですか？

現在も `pecl install xdebug` で3.5.3を導入できます。ただし公式ドキュメントではレガシーな方法に分類され、PIE（`pie install xdebug/xdebug`）が第一推奨です。Dockerの公式PHPイメージでは `pecl install xdebug-3.5.3` のように版番号を指定します。

### Xdebugのデフォルトポートはいくつですか？

Xdebug 3の既定は9003番です（`xdebug.client_port`）。Xdebug 2の既定は9000番で、Xdebug 3で変更されました。VS CodeのPHP Debugは9003番、PhpStormは9003番と9000番の両方で待ち受けます。

### Xdebug Cloudとは何ですか？

XdebugとIDEの間の接続を中継する、Xdebug開発者によるホスト型サービスです。XdebugとIDEの両方が公開IPのサービスへ接続するため、ファイアウォールやDockerのネットワーク構成でIDEへ直接つながらない環境でもステップ実行ができます。

## 関連記事

- [Laravel Debugbarの使い方｜導入・APP\_DEBUG設定・SQL確認とv4改称対応](/tech/details/4473/)
- [PHPStanとは？レベル0〜10の違いと導入・ベースライン運用【2.3対応】](/tech/details/12338/)
- [OPcacheとは？読み方とPHP 8.5の変更点・設定・確認方法](/tech/details/7965/)
- [Laragonとは｜料金・ライセンスと使い方・インストール手順【v8.7.0対応】](/tech/details/9030/)

---

出典: [Xdebugとは？PHPデバッグの使い方・インストール・php.ini設定・VSCode連携【3.5.3対応】](<https://www.issoh.co.jp/tech/details/7515/>)（株式会社一創）
