Xdebug+NetBeansによるCakePHPのデバッグ

Go previousメニューに戻る

はじめに

(2015/08/06) Apache の設定に漏れがあったので追記しました。


(2015/02/26) Cent OS 7 + Netbeans 8 の状況を追記しました。


(2013/09/19) CakePHP2 で LDAP 認証を使った Web アプリを開発しました。なんとか動くようになったので本番リリースしようと app/Config/core.php で debug を 2 から 0 に変えたら、何と認証が通らなくなりました。こんなこともあるんですね…。

当初、いつもの通り CakeLog::write() を駆使して追いかけようとしましたが、あるタイミングから1回の write() でログが2行出るとか謎現象が発生し、printf デバッグの限界を痛感。今回リモートデバッグに挑戦した次第です。

例示におけるサーバ側のプラットフォームには CentOS 6.4(64bit) を使っており、この中でApache + CakePHP 2.3.6 を動かしています。他の OS やディストリビューションをお使いの方は、yumなど固有のコマンド名を適宜読み替えてください。

またクライアント側は Windows 7 64bit Pro に NetBeans 7.3.1 という構成です。Windows 側には PHP や Apache の実行環境は入れていません。

CakePHPの導入

こちらをご覧ください。

Apache Web サーバの構成

いつもの通りの構成です。デバッグモードではこれで問題なく動いています。

root@rice:~# grep -E '^(Name|Inc)'  /etc/httpd/conf/httpd.conf
Include conf.d/*.conf
NameVirtualHost *:80
root@rice:~# cat /etc/httpd/conf.d/as-user.conf
<VirtualHost *:80>
    ServerAdmin     support@rice.example.com
    DocumentRoot    /var/www/as-user/
    ServerName      as-user2.example.com
    CustomLog       logs/as-user-access_log combined
    ErrorLog        logs/as-user-error_log
    Php_value       include_path   "."
# Xdebug を有効にする
    Php_flag    xdebug.remote_enable        On
    Php_flag    xdebug.remote_connect_back  On
# 以下、一時的な調査用
    RewriteLogLevel 3
    RewriteLog      rewrite.log
<VirtualHost>

Xdebugの導入

Xdebug は Web サーバ側に PHP の追加モジュールとして導入します。これはデバッグ時にはクライアントとしてサーバ側(今回は Windows7 上の NetBeans)に接続する形態を取るため、ネットワーク環境的に Linux サーバから Windows クライアントに対して TCP コネクションが張れる必要があります。なお初回実行時は Windows ファイアーウォールの警告が出ますが、ルールを有効にしないとデバッグできません。

なお、 Windows ファイアーウォールを有効にした後は、いったん NetBeans を再起動します。

Xdebugの導入はやや面倒ですが、前述の手順に従っている場合は以下のコマンド一発で導入可能です。

root@rice:~# yum install php56w-pecl-xdebug

NetBeans の導入

NetBeans は Java でよく使われる統合環境らしいです。CakePHP と Xdebug でぐぐった時にたまたま最初に引っかかったのでこちらにしましたが、Eclipse + PDT(PHP Development Tools) を使っている方の方が多いのかもしれません。

Windows 側でNetBeans のダウンロードページから PHP を含むものをダウンロードしてインストールします。

NetBeans を起動したらプロジェクトを開きます。

以下のような感じで設定しました。

プロジェクトを選択
名前と場所
リモート接続

リモート接続のためのssh環境は「管理」をクリックして別ウィンドウで設定します。

リモート接続の管理

SSH の秘密鍵ファイルについては常用している PuTTY のものは使えなかったので、サーバ側から OpenSSH の秘密鍵を持ってきて指定しました。

「次」をクリックすると指定したサーバに接続しようとします。

SSHの警告

「はい」をクリックすると、ディレクトリ一覧を表示します。

ディレクトリ一覧

そのまま「終了」をクリックすると、ディレクトリツリーを再帰的にローカル(Windows)側に転送してプロジェクトを作成します。ローカル側のファイルを編集すると、速やかにサーバ側に同期してくれます。

ディレクトリ一覧

うまく動かない?

通常のサイト利用は単に http://as-user2.example.com にアクセスします。すると以下の設定により app/webroot/ に飛ばされます。

root@rice:~# cat /var/www/as-user/.htaccess
<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]
<IfModule>

ところが NetBeans にはこれがわからないので、デバッグ時は明示的に開始ファイルを app/webroot/index.php にする必要があるらしいです。設定するにはプロジェクト名で右クリックしてプロパティを選択し、開始ファイルを指定します。

プロジェクトのプロパティ

ただ、これを設定しても最初はうまくいきませんでした。NetBeans 自体がわかっていなかったので、何か勘違いがあったのかもしれません。意味がないかもしれませんが、一応試行錯誤の手順を書いておきます。当初の現象は以下の通り。

no-webroot

このように、app/webroot/index.php にアクセスできないというもの。ただしこの画面は CakePHP が作ったものなので、Apache レベルの問題ではなく CakePHP がハンドリングできていないだけのはずです。

CakePHP のログには以下のように出ていました。

root@rice:~# cat /var/www/as-user/app/tmp/logs/error.log
2013-09-19 11:26:39 Error: [MissingActionException] Action AppController::webroot() could not be found.
Exception Attributes: array (
  'controller' => 'AppController',
    'action' => 'webroot',
    )
Request URL: /app/webroot/index.php?XDEBUG_SESSION_START=netbeans-xdebug
Stack Trace:
#0 /var/www/as-user/lib/Cake/Routing/Dispatcher.php(187): Controller->invokeAction(Object(CakeRequest))
#1 /var/www/as-user/lib/Cake/Routing/Dispatcher.php(162): Dispatcher->_invoke(Object(AppController), Object(CakeRequest), Object(CakeResponse))
#2 /var/www/as-user/app/webroot/index.php(110): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse))
#3 {main}

たしかに AppContoroller には webroot 用の action(ハンドラ)がなかったので、単純に定義してみました。

m-hotta@rice:~/as-user/app/Controller$ tail -6 AppController.php
    public  function    webroot()   {
        $this->redirect(array(
            'controller'    =>  'Users',
            'action'        =>  'index'));
    }
}

自分のケースではこのコードにより app/webroot/index.php のハンドリングが有効になってデバッグできるようになりました。ちなみに "CakePHP Xdebug ブレークポイント" でぐぐると困っている人がいろいろと見つかりますw。

デバッグ方法

行番号をクリックするとブレークポイントが設定されるので、後は「プロジェクトをデバッグ」をクリックしてデバッグを行います。

NetBeans

1行目で止まらないようにする

(2014/06/15 追加 - NetBeans IDE 8.0) デフォルトでは毎回最初の行で実行を停止するようになっています。慣れてきたら、以下の手順でこの設定を解除できます。
ツール(T)>オプション(O)>PHP>最初の行で停止 のチェックを外す。

CLI アプリのデバッグ方法

CLI アプリについては、以下の方法でデバッグできています。前提事項として、 NetBeans のインストールと実行は Linux の X Window System 上で行います。 CentOS の場合であれば Gnome 環境となります。

  1. Linux 環境がネットワーク上にある場合は、VNC 経由で接続します。
    事前に VNC による Windows から Linux へのログイン の環境を作っておいてください。
  2. 自ユーザ環境の .bashrc に以下の一文を追加します。
    export XDEBUG_CONFIG="idekey=netbeans-xdebug"
    
  3. Gnome にログインし直します。
    GUI 環境に接続後、ターミナルを開いて env を実行し、環境変数が正しく反映されていることを確認します。
  4. X 環境に NetBeans を導入します。一般ユーザ環境にそのまま入ります。
  5. アプリケーション>プログラミング から NetBeans を起動します。
  6. プロジェクトは以下の要領で作成します。
    1. プロジェクトの新規作成
    2. 既存のソースを使用するPHPアプリケーション
    3. ソース・フォルダ:cakeのトップディレクトリ
    4. 実行方法:スクリプト(コマンド行で実行)
    5. PHPインタプリタ:/usr/bin/php
    6. 開始ファイル:app/Console/cake.php
    7. 引数:適宜(最低でも第一引数は必要)
  7. /etc/php.ini に以下の設定を追加します。
    xdebug.remote_connect_back = on
    xdebug.remote_port    = 9000
    xdebug.remote_handler = dbgp
    xdebug.remote_enable = On
    xdebug.remote_log = /tmp/xdebug_remote.log
    xdebug.idekey = netbeans-xdebug
    
    (この設定はセキュリティに甘いところもあります。詳細は Xdebug のドキュメント を参照してください。)
Go previous