2013-06-05

●NetBeans と PHP コマンドライン起動のソースデバッグ

リモート環境にてコマンドライン起動のPHPのソースデバッグを行う方法を試行錯誤したメモです。
NetBeans と Xdebug をインストールしたけれどブレークポイントで実行が止まらない方の参考になれば幸いです。

●NetBeans IDE 7.3 と PHP CLI Xdebug 2.2 の設定

リモートのネットワーク環境と通信イメージ

 
  1. PHPをコマンドライン起動する。Xdebug からポート9000へ接続。デバッグするファイルのパスなどが返る。
  2. Home Gatesay の静的NAT機能で Client のポート9000に転送。
  3. NetBeans からデバッグを制御する要求を送る。ブレークポイントも送られる。
Home Gateway の設定
固定IPアドレス 10.0.0.1 のポート 9000 へのアクセスを Client(NetBeans)のIPアドレス 192.168.0.42 のポート 9000 へ転送する設定をします。(静的NAT設定)
また接続元のIPアドレスを Server Gatesay の 10.0.1.1 に制限すると安心です。
Xdebugの設定
通常は php.ini で設定すれば良いですが、今回のプロジェクトでは php.ini の変更を避けたいのとコマンド実行ユーザを特定したいため以下のようなシェルスクリプトを使うことにしました。
またうまく動作するまで remote_log を設定してみます。
#!/bin/sh
export XDEBUG_CONFIG="remote_enable=On idekey=netbeans-xdebug remote_host=10.0.0.1 remote_log=/tmp/xdebug_remote.log"
/usr/bin/php -d zend_extension="/usr/lib64/php/modules/xdebug.so" -f /home/user/project/batch/test.php
ダブルクリックで全行選択

 

  • xdebug.so へのパスはサーバーに合わせて変更してください。
  • 接続先ポートの既定値は 9000 です。NetBeansのデバッガ・ポートと異なる場合は remote_port=nnnn を XDEBUG_CONFIG の中に追加します。
NetBeans 7.3 の設定
  1. メニュー [ツール] [オプション] を選び タブ [PHP] [デバッグ] を選ぶ。

    • 「デバッガ・ポート」:Xdebug の remote_port と同じ値を指定します。
    • 「セッションID」:Xdebug の idekey と同じ値を指定します。
  2. メニュー [ファイル] [プロジェクトプロパティ] を選び、カテゴリの [実行構成] を選ぶ。

    • 「開始ファイル」:PHP CLI で起動するファイルを記述すれば確実です。任意のファイルでも大丈夫と思われます。但し「アップロードディレクトリ」の表示"sftp://10.0.1.1/home/user/project"と「開始ファイル」の値"batch/test.php"を合わせて"/home/user/project/batch/test.php"のパスがServerに存在するようにします。
    • 「リモート接続」:接続するServerを選択します。最初は[管理(M)]ボタンを押して次の画面のように設定します。
    • 「アップロードディレクトリ」:Serverのプロジェクトのソースファイルのトップディレクトリを調整します。
      次の画面の「初期ディレクトリ」の値と合わせてトップディレクトリを指定します。欄下に表示される"sftp://10.0.1.1/home/user/project"の値で確認してください。
  3. 前の画面の[実行構成] の 「リモート接続」の欄右の [管理(M)]ボタンを押す。

    • 「秘密鍵ファイル」:OpenSSH形式の鍵ファイルを指定します。PuTTYで生成したものはPuTTYgenでこの形式に変換できます。
      なおデバッグ操作だけであれば接続できなくても良いようです。ただNetBeansにて実際にファイルをアップロード・ダウンロードするためには接続可能な設定にします。
    • 「既知のホストファイル」:Serverに存在する任意のファイルを指定すれば良いと思われます。
    • 「初期ディレクトリ」:このリモート接続(sftp)でのトップディレクトリを指定します。

 

●ソースデバッグの実行

いよいよデバッグの実行です。

NetBeans の準備
  1. ブレークポイントの設定

    • 実行を一時停止させたいソースファイルを開いて行番号を選び赤く反転させます。
  2. デバッグセッションの開始

    • 実行するソースファイルを開き、メニュー [デバッグ] [ファイルをデバッグ] を選びます。
    • このときWWWブラウザでエラーのページが開きますが無視します。
    • 開くファイルはServer側のPHPで起動するファイル"/home/user/project/batch/test.php"に対応するローカルのファイルです。ブレークポイントを設定したファイルでない場合もあります。
PHPスクリプトの実行
  1. コマンドラインからシェルスクリプトを起動します。

    sudo -u apache /home/user/project/batch/test.sh
    
    • スクリプトがすぐに終了しなければうまく行っているかも!
NetBeans デバッグ操作
  1. ブレークポイントで停止

    • 実行直前のソース行が緑色に表示されば成功です。
    • ここからステップ実行や変数の値の参照などデバッグ作業ができます。
  2. デバッグセッションの終了

    • メニュー [デバッグ] [デバッガ・セッションを終了] を選びます。
    • このときWWWブラウザでエラーのページが開きますが無視します。

 

●トラブルシューティング

ブレークポイントで停止しない時は...次のパターン別に確認してみましょう。

remote_log が全く出力されない場合
Server での Xdebug の設定がうまく行っていない可能性があります。
シェルスクリプトで php -i を表示させて確認してみましょう。
#!/bin/sh
export XDEBUG_CONFIG="remote_enable=On idekey=netbeans-xdebug remote_host=10.0.0.1 remote_log=/tmp/xdebug_remote.log"
/usr/bin/php -d zend_extension="/usr/lib64/php/modules/xdebug.so" -i
ダブルクリックで全行選択

これを実行して以下の設定が含まれているか確認してみてください。

sudo -u apache /home/user/project/batch/php.sh | grep xdebug
xdebug support => enabled
...
XDEBUG_CONFIG => remote_enable=On idekey=netbeans-xdebug remote_host=10.0.0.1
 remote_log=/tmp/xdebug_remote.log

 
確認ポイント
  • zend_extension で指定する xdebug.so へのパス
  • XDEBUG_CONFIG の設定
remote_log に Could not connect to client. :-( が出力される場合
ネットワークの設定がうまく行っていない可能性があります。
 
/tmp/xdebug_remote.log

I: Connecting to configured address/port: 10.0.0.1:9000.
E: Could not connect to client. :-(
 
確認ポイント
  • 接続先(Home Gateway)のIPアドレスやポート番号の設定
  • Xdebug から Home Gateway までの通信
    一旦 Home Gateway の静的NAT設定を無効にしてHome Gateway のログで破棄されたパケットがあるか確認する手もあります。
  • Home Gatesay から Client(NetBeans) までの通信
    今回は問題なかったのですが、PCのセキュリティソフトがブロックしているかもしれません。
  • Client(NetBeans) から Xdebug への通信
    私の場合 Home Gateway にグローバルIPアドレスが2つあり、Server Gateway が許可していない方のアドレスから返信してました。Home Gateway から出る時の経路に注意でした。
remote_log の breakpoint_set file: に ローカルのパスが出力される場合
Server と Client(NetBeans) ファイルのパスのマッピングがうまく行っていない可能性があります。
 
/tmp/xdebug_remote.log

-> <init fileuri="file:///home/user/project/batch/test.php"></init> 
...
<- breakpoint_set
 file:///C:/Users/developer/Documents/NetBeansProjects/project/batch/test.php -n 6
 
確認ポイント
  • NetBeans の[プロジェクトプロパティ]の[実行構成]や[リモート接続の管理]のあたりのファイルパス関連
    HTTPでのデバッグとCLIでのデバッグでは違う設定にしないとうまく動かないことがあります。
  • NetBeans でデバッグを実行するファイルと Server のコマンドラインで実行するファイルは同じ?

 

おわりに
拙い説明ですみませんがご参考になれば幸いです。