目次
Xdebug
インストール
Yum
# yum list \*xdebug\* # yum install php-pecl-xdebug.i386
PECL
# dnf install php php-devel php-pear # pecl install xdebug PHP 7.2-7.4 の場合 # pecl install xdebug-3.1.6 # vi /etc/php.d/user.ini +zend_extension=/usr/lib64/php/modules/xdebug.so
プロファイリング
下準備
# mkdir /php-xdebug # chown apache /php-xdebug
/html/.htaccess
Linux の例
php_flag xdebug.profiler_enable 1 php_value xdebug.profiler_output_dir "/php-xdebug" php_flag xdebug.profiler_append 0 php_value xdebug.profiler_output_name "cachegrind.out.%u_%R"
Windows の場合、xdebug.profiler_output_dir を以下要領で変える。
php_value xdebug.profiler_output_dir "C:\app\php-52-ts\xdebug"
.user.ini
xdebug 2
- Chrome 拡張「Xdebug helper」を使って有効化する場合の例。
- xdebug.profiler_output_dir は、デフォルトの /tmp では駄目だった。(Amazon Linux 2) (実行ユーザーと同一ユーザーでシェルから確認した。)
xdebug.profiler_enable_trigger = on xdebug.profiler_enable_trigger_value = "XDEBUG_ECLIPSE" xdebug.profiler_output_dir = "/php-xdebug" xdebug.profiler_output_name = "cachegrind.out.%u_%R"
リモートデバッグ
VSCode
クライアント側
- SSH 接続で、PHP Debug by Xdebug の「Listen for Xdebug」を利用した。
- プラグインが Listen するポート (デフォルト 9003) は、サーバー上となる。よって、SSH トンネルを手動設定する必要は無い。
- configurations.hostname: “127.0.0.1” で、IPv4 リッスン可能。しかし、デフォルトの localhost 設定で、IPv6, IPv4 双方にアクセスを試みる様子だった。よって、通常この設定は不要そう。
- PHP by DEVSENSE のみでもデバッグできた。
サーバー側
- ページにアクセスすると、Xdebug から、プラグインが Listen するポート (デフォルト 9003) へアクセスする。
- 未検証だが、PHP コードから発火させる方法もありそう。その方が、IP 分岐など、運用への影響を抑えられそうな気もする。
PHP 5.4 (Xdebug 2.2.7) (FCGI)
実際に動作した設定。
- PHP 5.3.3 (Xdebug 2.1.4) (FPM) でも同様で動作した。
- .user.ini
xdebug.remote_enable = on xdebug.remote_autostart = on xdebug.remote_port = 9003
- FCGI のタイムアウトの延長に FcgidIOTimeout が有用だと思うが、
Context: server config, virtual host
なので、.htaccess では設定できないと考えられる。(他の回避方法があるか不明。)
PHP 5.6 (Xdebug 2.5.5)
実際に動作した設定。
- .htaccess
php_flag xdebug.remote_enable on php_flag xdebug.remote_autostart on php_value xdebug.remote_port 9003
PHP 7.4 (Xdebug 2.9.5)
「PHP 5.4 (Xdebug 2.2.7) (FCGI)」同様の設定で動作した。(/etc/php.d/*.ini に記述した。)
PHP 7.4 (Xdebug 3)
実際に動作した設定。
- PHP 7.2 (Xdebug 3.1.6) でも同様で動作した。
- /etc/opt/remi/php74/php.d/user.ini
# xdebug.client_host = "localhost" # xdebug.client_port=9003 xdebug.mode=develop,debug
- ドキュメントベースで確認し、
xdebug.client_host
とxdebug.client_port
は、デフォルト値なので不要そう。 - 公開サーバーで無差別に受け付けるのは危険を感じる。HTTP リクエスト側のIP制限などの対策が必要だと思う。
- .user.ini
xdebug.start_with_request=yes
- .htaccess
php_value xdebug.start_with_request yes
設定の記述先について
xdebug.mode
- 公式ドキュメントによると、 .htaccess 不可。Apache VHOST 不可。PHP-FPM プール不可(?)。
- .htaccess も .user.ini も不可。(実際に試した。)
- カンマ区切りで複数指定可能。
xdebug.start_with_request
- .htaccess も .user.ini も可能だった。(実際に試した。) 無論、php.ini も可能。
Docker 上の PHP をデバッグ
通常との差異。
php.ini
xdebug.client_host = host.docker.internal
.vscode/launch.json
{ "configurations": [ { "pathMappings": { "/var/www/app": "${workspaceRoot}", }, }, ], }
別の発火方法
xdebug.remote_autostart や xdebug.start_with_request を使わずデバッグする方法。その方が、多分安全。
WEB
- 問い合わせ文字列 XDEBUG_SESSION_START=<値> をセットする。(デフォルトでは値は何でも良い。空文字も可。)
- XDEBUG_SESSION_STOP で停止。
- セッション期間中は、クッキー XDEBUG_REMOTE_SESSION がセットされる。(毎回問い合わせ文字列をセットする必要はない。)
- クッキー XDEBUG_REMOTE_SESSION をセットする。
- PHP 5.6, Xdebug 2.5.5 で動作した。Xdebug 3 でも使えたと思う。
コマンドライン
- 環境変数 XDEBUG_SESSION をセットする。
- v2 では、XDEBUG_CONFIG を使う。
例
$ XDEBUG_SESSION=1 ./foo.php # sudo -u apache XDEBUG_SESSION=1 ./foo.php $ docker compose exec -T -e XDEBUG_SESSION=1 <サービス名> php
- あらかじめリモートデバッグの有効化が必要。php.ini を変更できない場合、スクリプト側で以下のような引数指定を行う対応も可。
PHP: syntax error, unexpected TC_STRING in Unknown on line 7
といったエラーが表示されるケースがあった。(関連情報) 実行され、デバッグも可能だった。
Xdebug2 の例
#!/bin/php -d xdebug.remote_enable=on -d xdebug.remote_port=9003
<?php
Xdebug3 の例
- 未検証
#!/bin/php -d xdebug.mode=develop,debug
<?php
資料
未編集原稿
.user.ini ; for xdebug 2 xdebug.remote_enable = ${PHPFPM_xdebug_remote_enable} xdebug.remote_autostart = ${PHPFPM_xdebug_remote_autostart} ; for xdebug 3 xdebug.start_with_request = ${PHPFPM_xdebug_start_with_request} .htaccess # 開発サイト # - 別名によるブレを回避するため HTTP_HOST を使わず、SERVER_NAME を使っている。(効果未検証) <If "%{SERVER_NAME} =~ /^dev\./"> SetEnv PHPFPM_xdebug_remote_enable on SetEnv PHPFPM_xdebug_remote_autostart on SetEnv PHPFPM_xdebug_start_with_request yes </If> # 本番サイト <Else> SetEnv PHPFPM_xdebug_remote_enable off SetEnv PHPFPM_xdebug_remote_autostart off SetEnv PHPFPM_xdebug_start_with_request no </Else>