PHPスクリプトをどのようにデバッグしますか?
エラー報告の使用など、基本的なデバッグについては認識しています。PHPEclipseでのブレークポイントのデバッグも非常に便利です。
phpStormまたは他のIDEでデバッグするための最良の(高速で簡単な)方法は何ですか?
あなたが言及したようなデバッグ機能を備えたEclipse環境をセットアップするには、Eclipse PDTを試してください。コードにステップ インする機能は、var_dump の古い方法よりもはるかに優れたデバッグ方法であり、さまざまなポイントで印刷して、フローのどこが間違っているかを確認できます。ただし、他のすべてが失敗し、SSHとvimしかない場合でも、var_dump()
/die()
コードが南に行く場所を見つける必要があります。
Firephpをfirebugのアドオンとして使用して、javascriptと同じ環境でphpをデバッグできます。
また、phpのプロファイリングには前述のXdebugを使用します。
これは私の小さなデバッグ環境です:
error_reporting(-1);
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_BAIL, 0);
assert_options(ASSERT_QUIET_EVAL, 0);
assert_options(ASSERT_CALLBACK, 'assert_callcack');
set_error_handler('error_handler');
set_exception_handler('exception_handler');
register_shutdown_function('shutdown_handler');
function assert_callcack($file, $line, $message) {
throw new Customizable_Exception($message, null, $file, $line);
}
function error_handler($errno, $error, $file, $line, $vars) {
if ($errno === 0 || ($errno & error_reporting()) === 0) {
return;
}
throw new Customizable_Exception($error, $errno, $file, $line);
}
function exception_handler(Exception $e) {
// Do what ever!
echo '<pre>', print_r($e, true), '</pre>';
exit;
}
function shutdown_handler() {
try {
if (null !== $error = error_get_last()) {
throw new Customizable_Exception($error['message'], $error['type'], $error['file'], $error['line']);
}
} catch (Exception $e) {
exception_handler($e);
}
}
class Customizable_Exception extends Exception {
public function __construct($message = null, $code = null, $file = null, $line = null) {
if ($code === null) {
parent::__construct($message);
} else {
parent::__construct($message, $code);
}
if ($file !== null) {
$this->file = $file;
}
if ($line !== null) {
$this->line = $line;
}
}
}
Xdebug と Notepad++ 用の DBGp プラグインは、負荷の高いバグ ハンティング用であり、FirePHP は軽量のものです。速くて汚い?dBugに勝るものはありません。
XDebugは開発に不可欠です。他の拡張機能の前にインストールします。エラーに関するスタック トレースが提供され、プロファイリングを簡単に有効にできます。
データ構造を簡単に見るには、 を使用しますvar_dump()
。print_r()
で囲む必要が<pre>
あり、一度に 1 つの変数しか出力しないため、使用しないでください。
<?php var_dump(__FILE__, __LINE__, $_REQUEST); ?>
実際のデバッグ環境では、私が見つけた最高のものはKomodo IDEですが、費用は $$ です。
PhpEdは本当に良いです。関数にステップ イン/オーバー/アウトできます。アドホック コードの実行、変数の検査、変数の変更を行うことができます。すごいです。
1) print_r() を使用します。TextMate には、これに展開される「pre」のスニペットがあります。
echo "<pre>";
print_r();
echo "</pre>";
2) Xdebug を使用していますが、Mac で GUI を正しく動作させることができませんでした。少なくとも、読み取り可能なバージョンのスタック トレースを出力します。
Zend Studio (5.5)をZend Platformと一緒に使用しました。これにより、コストはかかりますが、適切なデバッグ、ブレークポイント/コードのステップオーバーなどが可能になります。
正直なところ、print と print_r() を組み合わせて変数を出力します。多くの人が他のより高度な方法を使用することを好むことは知っていますが、これが最も使いやすいと思います.
Uni でマイクロプロセッサのプログラミングを行い、これさえ使用できなくなるまで、私はこれを十分に理解していなかったと言えます。
Derick RethansによるXdebugは、非常に優れています。しばらく前に使用しましたが、インストールがそれほど簡単ではないことがわかりました。一度終わったら、それなしでどうやって管理したのか理解できません:-)
Zend Developer Zone(Linuxへのインストールは簡単ではないようです)とFirefoxプラグインについての良い記事がありますが、これは私が使用したことはありません。
XDebug とEasy XDebug FireFox Add-on でNetbeans を使用しています
XDebug が Netbeans で実行される通常の方法は、URL を介してデバッグ セッションを登録することであるため、MVC プロジェクトをデバッグする場合、アドオンは不可欠です。アドオンを FireFox にインストールして、Netbeans プロジェクトのプロパティを設定します -> 構成の実行 -> 詳細設定を行い、[Web ブラウザを開かない] を選択します。これで、ブレーク ポイントを設定し、通常どおり Ctrl-F5 でデバッグ セッションを開始できます。 . FireFox を開き、右下隅にあるアドオン アイコンを右クリックして、ブレークポイントの監視を開始します。コードがブレークポイントに到達すると停止し、変数の状態と呼び出しスタックを調べることができます。
XDebugでNetbeansを使用しています。構成方法に関するドキュメントについては、Web サイトで確認してください。 http://php.netbeans.org/
出力を台無しにしたくない場合は、出力バッファリングが非常に便利です。私は自由にコメント/コメント解除できるワンライナーでこれを行います
ob_start();var_dump(); user_error(ob_get_contents()); ob_get_clean();
PhpEditにはデバッガーが組み込まれていますが、私は通常、echo()を使用することになります。およびprint_r(); 昔ながらのやり方!!
print_r / echoを使用して、IDE(PhpEd)のデバッグ機能を使用していることを理解するには時間がかかりすぎる、非常に厄介な問題については。私が使用した他のIDEとは異なり、PhpEdはほとんどセットアップを必要としません。私が遭遇する問題のためにそれを使用しない唯一の理由は、それが痛々しいほど遅いということです。速度がPhpEdまたは任意のphpデバッガーに固有であるかどうかはわかりません。PhpEdは無料ではありませんが、とにかくオープンソースデバッガー(前述のXDebugなど)の1つを使用していると思います。繰り返しになりますが、PhpEdの利点は、過去に非常に面倒だと思ったセットアップが不要なことです。
手動デバッグは一般的に私にとってより高速です-var_dump()
そしてdebug_print_backtrace()
あなたがあなたのロジックを武装させるために必要なすべてのツールです。
まあ、それはある程度、物事が南下する場所に依存します. それは私が分離しようとする最初のことであり、必要に応じて echo/print_r() を使用します。
注意: print_r() の 2 番目の引数として true を渡すと、印刷する代わりに出力が返されることをご存知ですか? 例えば:
echo "<pre>".print_r($var, true)."</pre>";
Rails が使えないときは CakePHP をよく使います。エラーをデバッグするには、通常error.log
、tmp フォルダーで を見つけ、コマンドを使用してターミナルで末尾に表示します...
tail -f app/tmp/logs/error.log
ケーキから実行中のダイアログが表示されます。これは、使用できるコードの途中で何かを出力したい場合に非常に便利です。
$this->log('xxxx');
これにより、通常、何が起こっているか/間違っているかについての良いアイデアが得られます。
print_r( debug_backtrace() );
またはそのようなもの:-)
Nusphere は php nusphereの優れたデバッガーでもあります
Komodo IDE は xdebug とうまく連携し、remore デバッグでも機能します。最小限の構成が必要です。必要なのは、ブレークポイントでコードをステップ実行するために Komodo がローカルで使用できるバージョンの php だけです。スクリプトを komodo プロジェクトにインポートした場合は、Java プログラムをデバッグするために Eclipse 内で設定するのと同じように、マウス クリックでブレークポイントを設定できます。リモートデバッグは、MACまたはLinuxデスクトップを使用している場合に設定が非常に簡単なローカルデバッグセットアップよりも、正しく機能させるのが明らかに難しいです(ワークスペースでリモートURLをphpスクリプトにマップする必要がある場合があります)。 .
組み込みのデバッガーを使用して、Eclipseにzendstudioを使用します。xdebugを使用したeclipsepdtを使用したデバッグと比較すると、まだ低速です。うまくいけば、それらの問題が修正され、速度は最近のリリースよりも向上していますが、それでもステップオーバーには2〜3秒かかります。zend firefoxツールバーは本当に物事を簡単にします(次のページ、現在のページなどをデバッグします)。また、コードのベンチマークを行い、円グラフ、実行時間などを提供するプロファイラーも提供します。
コードの機能やパフォーマンスに影響を与えることなく、環境を完全に制御できる SAPI モジュールとして実装されたインタラクティブなステップスルー PHP デバッガー。PHP 5.4+ 用の軽量で強力な使いやすいデバッグ プラットフォームを目指しており、PHP 5.6 ですぐに使用できます。
機能は次のとおりです。
スクリーンショットを参照してください。
ホームページ: http://phpdbg.com/
これは、ライブラリ (実際にはファイル) を使用して PHP スクリプトをデバッグするのが非常に簡単です。
必要な唯一のことは、以下のように 1 つのファイルを含めることです (コードの先頭に):
require('php_error.php');
\php_error\reportErrors();
次に、すべてのエラーから、バックトレース、コード コンテキスト、関数の引数、サーバー変数などの情報が得られます。例:
機能は次のとおりです。
ホームページ: http://phperror.net/
GitHub: https://github.com/JosephLenton/PHP エラー
私のフォーク (追加の修正あり): https://github.com/kenorb-contrib/PHP-Error
システムがDTrace 動的トレース(OS X にデフォルトでインストール) をサポートし、PHP が--enable-dtrace
デフォルトで有効になっている DTrace プローブを有効にしてコンパイルされている場合 ( )、このコマンドを使用すると、PHP スクリプトをすぐにデバッグできます。
sudo dtrace -qn 'php*:::function-entry { printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }'
したがって、次のエイリアスがrcファイル (例: )~/.bashrc
に追加されているとします。~/.bash_aliases
alias trace-php='sudo dtrace -qn "php*:::function-entry { printf(\"%Y: PHP function-entry:\t%s%s%s() in %s:%d\n\", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }"'
覚えやすいエイリアスを使用してスクリプトをトレースできますtrace-php
。
より高度な dtrace スクリプトを次に示します。これを に保存しdtruss-php.d
、実行可能 ( chmod +x dtruss-php.d
) にして実行します。
#!/usr/sbin/dtrace -Zs
# See: https://github.com/kenorb/dtruss-lamp/blob/master/dtruss-php.d
#pragma D option quiet
php*:::compile-file-entry
{
printf("%Y: PHP compile-file-entry:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1));
}
php*:::compile-file-return
{
printf("%Y: PHP compile-file-return:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), basename(copyinstr(arg1)));
}
php*:::error
{
printf("%Y: PHP error message:\t%s in %s:%d\n", walltimestamp, copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::exception-caught
{
printf("%Y: PHP exception-caught:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::exception-thrown
{
printf("%Y: PHP exception-thrown:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::execute-entry
{
printf("%Y: PHP execute-entry:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::execute-return
{
printf("%Y: PHP execute-return:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::function-entry
{
printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::function-return
{
printf("%Y: PHP function-return:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::request-shutdown
{
printf("%Y: PHP request-shutdown:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
php*:::request-startup
{
printf("%Y, PHP request-startup:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
ホームページ: GitHubの dtruss-lamp
簡単な使い方は次のとおりです。
sudo dtruss-php.d
.php -r "phpinfo();"
。それをテストするには、次の方法で任意の docroot に移動し、index.php
PHP 組み込みサーバーを実行できます。
php -S localhost:8080
その後、http://localhost:8080/でサイトにアクセスできます(または、都合のよいポートを選択します)。そこからいくつかのページにアクセスして、トレース出力を確認します。
注: dtrace はデフォルトで OS X で利用できます。Linux では、おそらくdtrace4linuxが必要になるか、他の代替手段を確認してください。
参照: php.net でのPHP と DTraceの使用
または、SystemTap SDT 開発パッケージ (例: yum install systemtap-sdt-devel
) をインストールして、SystemTap トレースを確認します。
all_probes.stp
以下は、SystemTap を使用して PHP スクリプトを実行している間、すべてのコア PHP 静的プローブ ポイントをトレースするためのサンプル スクリプト ( ) です。
probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
printf("Probe error\n");
printf(" errormsg %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
printf("Probe exception__caught\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
printf("Probe exception__thrown\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
printf("Probe execute__entry\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
printf("Probe execute__return\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
printf("Probe function__entry\n");
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
printf("Probe function__return: %s\n", user_string($arg1));
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
printf("Probe request__shutdown\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
printf("Probe request__startup\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
使用法:
stap -c 'sapi/cli/php test.php' all_probes.stp
参照: php.net のPHP DTrace 静的プローブでの SystemTap の使用
本番環境では、error_log() を使用して関連データをサーバーのエラー ログに記録します。
ほとんどのバグは、いくつかの重要な変数を単に ing するだけで簡単に見つけることができますがvar_dump
、開発するアプリケーションの種類によって明らかに異なります。
より複雑なアルゴリズムの場合、ステップ/ブレークポイント/ウォッチ機能が非常に役立ちます (必要でない場合)。
通常、ファイルに保存し、デバッグ情報を保存し、最終的に共通のフッターに再印刷できるカスタム ログ関数を作成します。
このタイプのデバッグが半自動化されるように、共通の Exception クラスをオーバーライドすることもできます。
コードをステップ実行するときに変数の値が変化するのを監視できる統合デバッガーは、非常に優れています。ただし、サーバー上でソフトウェアをセットアップし、クライアント上である程度の構成を行う必要があります。どちらも、正常に機能するために定期的なメンテナンスが必要です。
print_r は簡単に記述でき、どのようなセットアップでも動作することが保証されています。
+1 print_r() の場合。オブジェクトまたは変数の内容をダンプするために使用します。読みやすくするには、ソースを表示する必要がないように pre タグを付けます。
echo '<pre>';
print_r($arrayOrObject);
また var_dump($thing) - サブシングのタイプを確認するのに非常に便利です
問題によっては、error_reporting(E_ALL) とエコー テストを組み合わせて使用するのが好きです (最初にエラーが発生した問題のある行/ファイルを見つけるためです。行/ファイルが必ずしも正しいとは限りません)、IDE ブレース マッチング(「解析エラー: 構文エラー、予期しない $end」の問題を解決するため)、および print_r(); 出口; ダンプ (実際のプログラマーはソースを表示します;p)。
また、「memory_get_usage();」で phpdebug (sourceforge を確認) を打ち負かすことはできません。および「memory_get_peak_usage();」問題のある領域を見つけます。