💬

PHP のコマンドラインとかで xdebug が動かなくて困ってる時に

2021/09/04に公開

PHPみたいな忖度の激しい言語では、xdebugの使用が基本であるにも関わらず、その設定についてはqiitaのコピペやら勘やらで凌いでる人がほとんどだと思われるが、個人的に腑に落ちたので共有しておく。

xdebugでデバッグモード&ステップトレース等が機能する条件

  • 条件としてはどうやら後述の3つしかなさそう。
  • どれがが掛けても、IDE側ではステップトレースは始まらない。
  • リモートPHP側だけデバッグモードに入った場合は、実行がガッツリ固まる。

条件1:リモートで xdebugのデバッグモードが起動できること

  • phpにxdebugモジュールを組み込む。のは当然として....
  • php.ini に auto_start=1 && remote_enable=1 を書く。
    • これだけでは実はトレースモードは動いてない。起動できるようにしました。というだけなのだ。
    • mod_php/php-fpm/php-cgiの場合、URLパラメタから起動制御できるようになっている。
       - まあこの場合は素直にIDEの機能を使えるはず。

コマンドラインの場合

  • XDEBUG_CONFIG環境変数で、外から与える。
  • 内容は php.iniのxdebugセクションで書ける内容のほとんどだ。
  • 故に、php.ini で充分な設定があれば、空文字でも動いてしまうらしい。
  • デバッグモード対象は、XDEBUG_CONFIG環境変数が効く範囲。

php-fpm/mod_php/php-cgiの場合

  • URLパラメタを使う場合
  • URLパラメタに XDEBUG_SESSION_START=XXXXを付加すれば起動する。
  • デバッグモード対象は、その後に実行するスクリプトの全て。
  • 言い換えると、以降、そのサーバでのPHPの実行は全てステップトレースが掛かる。
  • 何時までレスポンスが来ないことになる。
  • URLパラメタに XDEBUG_SESSION_STOP_NO_EXEC=XXXXを付加すれば終了している。
  • リクエストのクッキーから認証する方法もあるらしいのだが小生は存じませんので言及は控える。

条件2: リモートからIDE側のTCPポート9000に接続できること

  • IDE側で、「デバッグ」を始めないとそもそもポートの待受はありません。
  • telnet {IDE側ホスト} 9000でも確認できる。
  • 接続が成功すれば、リモートの実行は少なくとも止まる。
  • リモートとIDEが別のマシンで動いてる場合(VMを使ってる場合はよくあるだろう)、どうにかしてIDEの稼働しているホスト名を与える必要がある。

ホスト名指定方法

次の何れかで指定する。
WEBの場合は前者が、コマンドラインなら後者の方がやや汎用性はあると思われる。

  • remote_connect_back=1 にして $_SERVER["REMOTE_ADDR"]を使う
  • remote_host= を指定する

remote_connect_backという表記が紛らわしいだが、リモートから接続に来ることは変わりはない。

条件3:リモートと同じフルパス名のPHPファイルを、IDE側も持っていること

  • xdebugの通信では、「このファイルのn行目で止まった」という情報しかやりとりしかしないため
  • まあ、他にどうしようもないのだが。
  • これが一致しないと、IDE側でデバッグが始まりません。
  • 大概のIDEでは、path mappingと呼ぶ機構で、地元のファイル位置に読み替えて帳尻を合わせてくれる。
  • コマンドラインスクリプトをテストしてる場合であれば、どっちも /tmp に移動するという手もある。

Discussion