PHP の変数をトレースする HTTPTrace をちょっと改造してみた
2007-08-25-1: [PHP]
HTTPTrace とは、Windows アプリケーションと連動して PHP の変数の内容を表示するツールです。
以下のページにて配布されています。
- 過去と他人はかえられないが、未来と自分はかえられる - [PHP]値を調べたい時に外部に出力するツール(var_dumpするよか便利)
http://d.hatena.ne.jp/magiwo/20070821
HTTPTrace は print_r() や var_dump() と異なり、ブラウザなどの画面ではなく Windows アプリケーションに変数の内容を表示するのが特長です。
面白そうなので少し試してみました。
まず、HTTPTraceServer.exe を起動して [Start] を選択します。このアプリケーションが PHP から変数の内容を受け取る HTTP サーバになっているようです。
次にサンプルプログラムを動かします。
// HTTPTrace ライブラリ
require_once 'htrace.php';
// HTTPTraceServer.exe を実行しているマシンの設定
htrace_set('192.168.1.100', 6006);
// 変数の内容を送信
htrace($_SERVER);
これをブラウザで実行すると HTTPTraceServer.exe は以下のように表示されます。
使い方はいたって簡単ですが、いくつか気づいた点があったので改造してみました。
1. allow_call_time_pass_reference = Off のとき警告がでる。
php,ini などで allow_call_time_pass_reference が Off (デフォルトは On) の場合は、以下のように警告が表示されます。
Warning: Call-time pass-by-reference has been deprecated
ソースを見ると fsockopen() の 第 3, 4 引数をリファレンスで渡しているのが原因で、これはリファレンスで渡す必要がないので、修正しました。
// 修正前
$fp = fsockopen($host, $port, &$err_num, &$err_msg, 1);
// 修正後
$fp = fsockopen($host, $port, $err_num, $err_msg, 1);
2. HTTPTraceServer.exe が起動していないとき警告がでる。
当たり前といえば、当たり前ですが若干気になったのでエラー制御演算子 (@) で警告が出ないようにしました。
// 修正前
$fp = fsockopen($host, $port, $err_num, $err_msg, 1);
// 修正後
$fp = @fsockopen($host, $port, $err_num, $err_msg, 1);
3. ソースファイルのパスが UNIX 環境でうまく区切れていない
HTTPTraceServer.exe は htrace() されたソースファイルをツリー上に表示してくれて非常に便利なのですが、UNIX 環境ではうまく表示されません。例えば以下のようにツリーではなく一行で表示されます。
%2Fhome%2Fhttpd%2Fpocari%2FHTTPTrace-0.1.0%2Fsample.php
Windows 環境を想定しているのかパスの分解が \ (バックスラッシュ) になっていたので、DIRECTORY_SEPARATOR (PHP4 >= 4.0.7, PHP 5) を使って、これを修正しました。
// 修正前
$exp = explode('\\', $debug['file']);
// 修正後
$exp = explode(DIRECTORY_SEPARATOR, $debug['file']);
これで無事にソースがツリー上に表示されるようになりました。
4. 何かしらの定数で htrace() を実行しないようにしたい
具体的には USE_HTRACE という定数を実装して、これが false の場合は htrace() が無効になるようにしました。
// 修正前
function htrace($vars, $stop=false)
{
$trace = debug_backtrace();
$debug = array_shift($trace);
$exp = explode('\\', $debug['file']);
$key = '';
foreach ($exp as $num=>$dt) {
$key .= rawurlencode($dt).'/';
}
$key .= sprintf("%05d", $debug['line']);
$inc = new HTTPTraceClient();
$inc->ModeGlobal();
$inc->SendValue($key, $vars, $stop);
}
function htrace_set($ip='localhost', $port=6006)
{
$inc = new HTTPTraceClient();
$inc->ModeGlobal(array('ip'=>$ip, 'port'=>$port));
}
// 修正後
if (!defined('USE_HTRACE')) {
define('USE_HTRACE', true);
}
if (USE_HTRACE) {
function htrace($vars, $stop=false)
{
$trace = debug_backtrace();
$debug = array_shift($trace);
$exp = explode(DIRECTORY_SEPARATOR, $debug['file']);
$key = '';
foreach ($exp as $num=>$dt) {
$key .= rawurlencode($dt).'/';
}
$key .= sprintf("%05d", $debug['line']);
$inc = new HTTPTraceClient();
$inc->ModeGlobal();
$inc->SendValue($key, $vars, $stop);
}
function htrace_set($ip='localhost', $port=6006)
{
$inc = new HTTPTraceClient();
$inc->ModeGlobal(array('ip'=>$ip, 'port'=>$port));
}
} else {
function htrace() {}
function htrace_set() {}
}
これを利用することで、htrace.php を require/include する前に USE_HTRACE を false に設定すれば htrace() は何もしなくなって便利です。
// htrace を無効にする
define('USE_HTRACE', false);
require_once 'htrace.php';
htrace_set('192.168.1.100', 6006);
// なにもしない
htrace($_SERVER);
以上のパッチを以下においておきます。
- HTTPTrace-0.1.0.diff
http://pocari.org/tools/HTTPTrace/HTTPTrace-0.1.0.diff
このような PHP のデバッグツールは大変ありがたいです。使いどころによっては大変威力を発揮するツールだと思います。
- 追記 (2007-08-31)
上記パッチを適用していただきました。ありがとうございます。
http://d.hatena.ne.jp/magiwo/20070830