PHPスクリプトをどのようにデバッグしますか?[閉まっている]


403

PHPスクリプトをどのようにデバッグしますか?

Error Reportingの使用などの基本的なデバッグを知っています。PHPEclipseでのブレークポイントのデバッグも非常に便利です。

何が最良の phpStormにおけるデバッグや他のIDEに(迅速かつ簡単の点で)方法はありますか?




40
これは素晴らしい質問だと思います!PHPのデバッグ方法がわからないときは、質問の言い方すらわからず、これより正確な方法もわかりません。だから、それはスタックのルールに従わないかもしれませんが、それは確かに私たち、初心者、多くに役立ちます!
ミハエラ2014

1
php5.4以降、phpdbg(phpdbg.com)と呼ばれる新しいコマンドラインインターフェースデバッガが導入されました。PHP5.6にはデフォルトのphpdbgが付属しています。
Ganesh Patil 2014年

1
XDebugについて聞いたことがありますか?:)
Pratik、2015年

回答:


145

Eclipse PDTを試して、前述のデバッグ機能を備えたEclipse環境をセットアップしてください。コードにステップインする機能は、var_dumpの古いメソッドをデバッグし、さまざまな時点で出力してフローがどこで問題が発生しているかを確認するためのはるかに優れた方法です。他のすべてが失敗しても、私が持っているのはSSHとvimだけですが、コードはどこに行くのかをvar_dump()/ die()調べます


35
この関数を使用する必要があります:kill($ data){die(var_dump($ data)); }それは私が今までTBH書かれている10個の文字を入力して、最高の機能を節約します:)
AlexMorley・フィンチ

2
試してみてくださいgithub.com/tomasfejfar/enhanced-dump :)を
トマーシュFejfar

2
「var_dump」を美化する方法はありますか?
RPDeshaies 2014年

6
@ AlexMorley-Finchあなたを挙げさせてくださいkill($data) { echo "<pre>"; var_dump($data); echo "</pre>"; exit; }
Francisco Presencia 2015年

2
リンクは、信じられないほどのWebアーカイブを介して「回復​​可能」です。最後のチェックは、2015年5月7日現在です。
グルーバー2016

80

FirephpをFirebugのアドオンとして使用して、JavaScriptと同じ環境でPHPをデバッグできます。

phpのプロファイリングには、前述のXdebugも使用しています。


3
そして、FirePHPを使用するためのクイックガイドを以下に示し
Mihaela

38

これは私の小さなデバッグ環境です:

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;
        }
    }
}

2
ありがとうございました。それは私の日を救った。(私はそのE_STRICTを削除する必要がありました)
Sec

4
assert_callcackheh
Madbreaks

32

XdebugとNotepad ++用のDBGpプラグインは、強力なバグハンティング用で、FirePHPは軽量のもの用です。早くて汚い?dBugに勝るものはありません。


DBGpプラグインは現在のバージョンのnotepad ++ / xdebugでは機能せず、修正する予定はありません。ここに
Joe

26

XDebugは開発に不可欠です。他の拡張機能の前にインストールします。エラーのスタックトレースが得られ、プロファイリングを簡単に有効にできます。

データ構造を簡単に確認するには、を使用しますvar_dump()。あなたはprint_r()それを囲む必要が<pre>あり、一度に1つの変数のみを印刷するので、使用しないでください。

<?php var_dump(__FILE__, __LINE__, $_REQUEST); ?>

実際のデバッグ環境の場合、私が見つけた最良の環境はKomodo IDEですが、$$かかります。


19

PhpEdは本当に良いです。関数にステップイン/オーバー/アウトできます。アドホックコードの実行、変数の検査、変数の変更を行うことができます。すごいです。


4
私はPhpEdを使用しましたが、NetBeansやEclipseなどの実際のIDEと比較した場合、それについて優しい言葉はありません。また、このコメントは質問に役立つものを追加しません。-1
シリコンロックスター2013

PhpED Professionalを購入する前に、ほとんどのIDE(Zend、NetBeans、Eclipseを含む)を試してみました。これは数年前だったので、他の人はそれ以降改善されたかもしれませんが、それらのほとんどはJavaで記述されていたため、非常に遅くなりました。それが(私にとって)最もはっきりしていて、決定が非常に簡単だったときに、誰かがどのようにして「親切な言葉を言わない」ことができるのかわかりません。
lm713 2015年

17

1)print_r()を使用します。TextMateには、これに拡張される「pre」のスニペットがあります。

echo "<pre>";
print_r();
echo "</pre>";

2)Xdebugを使用していますが、MacでGUIを正常に機能させることができません。少なくとも、読み取り可能なバージョンのスタックトレースを出力します。


エコー "</ pre>"を意味していると思います。最後に。
altermativ 2009

9
関数に「true」を渡して文字列を返すこともできます。これは、次のことを実行できることを意味しますecho '<pre>', print_r($var, true), '</pre>';
。– DisgruntledGoat


16

正直なところ、変数を出力するためのprintとprint_r()の組み合わせ。多くの人が他のより高度な方法を使用することを好むことを知っていますが、これが最も簡単に使用できると思います。

私は、Uniでマイクロプロセッサプログラミングを実行して、これを使用することができなくなるまで、これを十分に理解しなかったと言います。


printとprint_rについて言及していただき、ありがとうございます。基本的な印刷を使用して、コードが特定のポイントまで実行されたかどうかを確認します。これにより、問題の特定に役立ちます。
ブラッド、

printとvar_dump()の両方を使用しています。印刷を使用してデバッグメッセージとデバッグ情報を表示し、var_dumpを使用して変数の状態を示します。
ジョシュアK

14

Derick RethansによるXdebugは非常に優れています。私はそれを少し前に使用しましたが、インストールはそれほど簡単ではないことがわかりました。いったん完了すると、それなしでどのように管理したか理解できなくなります:-)

Zend Developer Zone(Linuxへのインストールは簡単ではないようです)と、私が使用したことのないFirefoxプラグインについての良い記事があります。


2
それをインストールするだけではイライラします。Eclipseで動作するようにXdebugを構成することは、悪夢になる可能性があります。CentOS 5にXdebugをインストールすることはできましたが、EclipsePDT + Xdebugは協力したくありません:(
Jahangir


11

XbeanとEasy XDebug FireFoxアドオンで Netbeansを使用しています

MBeanプロジェクトをデバッグする場合、アドオンは不可欠です。NetbeansでXDebugを実行する通常の方法は、URLを介してdbugセッションを登録するためです。FireFoxにアドオンをインストールしたら、Netbeansプロジェクトのプロパティを設定します->設定を実行->詳細設定を選択し、 "Webブラウザを開かない"を選択しますブレークポイントを設定し、通常どおりCtrl-F5でデバッグセッションを開始できます。FireFoxを開き、右下隅にあるアドオンアイコンを右クリックして、ブレークポイントの監視を開始します。コードがブレークポイントに到達すると停止し、変数の状態と呼び出しスタックを検査できます。



9

PhpEditにはデバッガが組み込まれていますが、私は通常、echo()を使用します。およびprint_r(); 昔ながらの方法!


8

print_r / echoを使用してIDEの(PhpEd)デバッグ機能を使用して理解するのに時間がかかり過ぎる、実際に骨の折れる問題については。私が使用した他のIDEとは異なり、PhpEdはほとんどセットアップを必要としません。私が遭遇する問題のためにそれを使用しない唯一の理由は、それが痛々しく遅いということです。速度の低下がPhpEdやphpデバッガに固有のものかどうかはわかりません。PhpEdは無料ではありませんが、いずれにせよ(前述のXDebugのような)オープンソースデバッガーの1つを使用していると思います。繰り返しになりますが、PhpEdの利点は、これまで私がかなり面倒であると思っていたセットアップが不要なことです。


2
PHPEdデバッガーは、実際にはPHPEdを書いたのと同じ人によって書かれており、私はそれがオープンソースではないと確信しています。少なくともPHPEdにはソースが同梱されていませんが、代わりに.soと.dllがコンパイルされています。
Artem Russakovskii

4

マニュアルのデバッグは、私のために、一般的に高速です- var_dump()そしてdebug_print_backtrace()あなたとあなたのロジックを武装するために必要なすべてのツールです。


3

まあ、ある程度それは物事が南に行くところに依存します。それが私が最初に分離しようとしていることであり、次に、必要に応じてecho / print_r()を使用します。

注:皆さんは、print_r()の2番目の引数としてtrueを渡すことができ、出力する代わりに出力を返すことを知っていますか?例えば:

echo "<pre>".print_r($var, true)."</pre>";

2
私はそれをdebugという関数にラップします。だから私はdebug($ var);
jdelator 2008年

3

Railsが不可能な場合、私はよくCakePHPを使用します。エラーをデバッグするには、通常error.log、tmpフォルダーでを見つけて、次のコマンドでターミナルにテールします...

tail -f app/tmp/logs/error.log

それはあなたが何が起こっているかのケーキからダイアログを実行させます、あなたがそれに使用できるコードの途中で何かにそれを出力したいなら、それはかなり便利です。

$this->log('xxxx');

これは通常、何が起こっているか、何が間違っているかについての良い考えをあなたに与えることができます。



2

Komodo IDEは、さらにデバッグする場合でも、xdebugでうまく機能します。最小限の構成が必要です。必要なのは、コモドがブレークポイントでコードをステップ実行するためにローカルで使用できるphpのバージョンです。スクリプトをkomodoプロジェクトにインポートした場合、JavaプログラムをデバッグするためにEclipse内でスクリプトを設定する方法と同じように、マウスクリックでブレークポイントを設定できます。MACまたはLinuxデスクトップを使用している場合に構成するのが非常に簡単なローカルデバッグセットアップよりも、リモートデバッグを正しく機能させるには、明らかにリモートデバッグの方が難しい(ワークスペースでphpスクリプトを使用してリモートURLをマップする必要がある場合がある)。 。



2

コーディング時に数え切れないほどの時間を節約できる多くのPHPデバッグ手法があります。効果的ですが基本的なデバッグ手法は、エラー報告をオンにすることです。もう1つの少し高度な手法には、印刷ステートメントの使用が含まれます。これは、実際に画面に表示されているものを表示することで、よりわかりにくいバグを特定するのに役立ちます。PHPeclipseは、一般的な構文エラーを強調表示できるEclipseプラグインで、デバッガーと組み合わせて使用​​してブレークポイントを設定できます。

display_errors = Off
error_reporting = E_ALL 
display_errors = On

そしてまた使用された

error_log();
console_log();


1

組み込みのデバッガーで日食にzend studioを使用します。それは、xdebugを使用したeclipse pdtを使用したデバッグと比較すると、まだ遅いです。それらがこれらの問題を修正することを願っています。速度は最近のリリースよりも向上していますが、それでもなおステップオーバーには2〜3秒かかります。zend firefoxツールバーは、物事を本当に簡単にします(次のページ、現在のページなどのデバッグ)。また、コードをベンチマークし、円グラフや実行時間などを提供するプロファイラーも提供します。


1

ほとんどのバグはvar_dump、いくつかの主要な変数を使用するだけで簡単に見つけることができますが、開発するアプリケーションの種類によって異なります。

より複雑なアルゴリズムでは、ステップ/ブレークポイント/ウォッチ機能が非常に役立ちます(必要でない場合)


1

PHP DBG

コードの機能やパフォーマンスに影響を与えることなく、環境を完全に制御できるSAPIモジュールとして実装されたインタラクティブなステップスルーPHPデバッガー。PHP 5.4以降用の軽量で強力な使いやすいデバッグプラットフォームを目指しており、PHP 5.6に付属しています。

機能が含まれます:

  • ステップスルーデバッグ
  • 柔軟なブレークポイント(クラスメソッド、関数、ファイル:行、アドレス、オペコード)
  • 組み込みのeval()でPHPに簡単にアクセス
  • 現在実行中のコードへの簡単なアクセス
  • ユーザーランドAPI
  • SAPIに依存しない-簡単に統合
  • PHP構成ファイルのサポート
  • JITスーパーグローバル-自分で設定!!
  • オプションのreadlineサポート-快適な端末操作
  • リモートデバッグサポート-バンドルされたJava GUI
  • 簡単操作

スクリーンショットを見る:

PHP DBG-ステップスルーデバッグ-スクリーンショット

PHP DBG-ステップスルーデバッグ-スクリーンショット

ホームページ:http : //phpdbg.com/

PHPエラー -PHPのエラー報告の改善

これは、PHPスクリプトのデバッグに非常に使いやすいライブラリ(実際にはファイル)です。

あなたがしなければならない唯一のことは、以下のように(コードの最初に)1つのファイルを含めることです:

require('php_error.php');
\php_error\reportErrors();

その後、すべてのエラーは、バックトレース、コードコンテキスト、関数の引数、サーバー変数などの情報を提供します。次に例を示します。

PHPエラー|  PHPのエラー報告の改善-バックトレースのスクリーンショット PHPエラー|  PHPのエラー報告の改善-バックトレースのスクリーンショット PHPエラー|  PHPのエラー報告の改善-バックトレースのスクリーンショット

機能は次のとおりです。

  • 使用するのは簡単です、それは1つのファイルです
  • 通常のリクエストとajaxyリクエストでブラウザに表示されるエラー
  • AJAXリクエストは一時停止され、自動的に再実行できます
  • エラーを可能な限り厳密にする(コードの品質を向上させ、パフォーマンスを向上させる傾向がある)
  • スタックトレース全体のコードスニペット
  • 詳細情報(完全な関数シグネチャなど)を提供します
  • 明らかに間違っているいくつかのエラーメッセージを修正しました
  • 構文の強調表示
  • きれいに見えます!
  • カスタマイズ
  • 手動でオンとオフを切り替える
  • エラー報告なしで特定のセクションを実行する
  • スタックトレースでコードを強調表示しないようにするファイルを無視する
  • アプリケーションファイル; エラーが発生すると、これらが優先されます。

ホームページ:http : //phperror.net/

GitHub:https : //github.com/JosephLenton/PHP-Error

私のフォーク(追加の修正を含む):https : //github.com/kenorb-contrib/PHP-Error

DTrace

システムが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

簡単な使用法を次に示します。

  1. 実行:sudo dtruss-php.d
  2. 別の端末の実行には:php -r "phpinfo();"

これをテストするには、次のようにして、任意のdocrootに移動しindex.php、PHP組み込みサーバーを実行します。

php -S localhost:8080

その後、http:// localhost:8080 /のサイトにアクセスできます(または、都合のよいポートを選択します)。そこからいくつかのページにアクセスして、トレース出力を確認します。

注:DtraceはデフォルトでOS Xで使用できます。Linuxでは、おそらくdtrace4linuxが必要か、他の代替手段を確認してください。

参照:php.netでのPHPとDTraceの使用


SystemTap

または、SystemTap SDT開発パッケージ(などyum install systemtap-sdt-devel)をインストールして、SystemTapトレースを確認します。

all_probes.stpSystemTapで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の使用


0

print_r()の場合は+1。オブジェクトまたは変数の内容をダンプするために使用します。読みやすくするために、ソースを表示する必要がないようにpreタグを使用してください。

echo '<pre>';
print_r($arrayOrObject);

また、var_dump($ thing)-これはサブシングのタイプを確認するのに非常に役立ちます




0

エコーテストと混合されたerror_reporting(E_ALL)の組み合わせが好きな問題に応じて(問題のある行/ファイルを見つけるために、最初にエラーが発生しました; phpが常に行/ファイルが正しいとは限らないことを知っていますか?)、IDEブレースマッチング(「解析エラー:構文エラー、予期しない$ end」の問題を解決するため)、およびprint_r(); 出口; ダンプ(実際のプログラマはソースを表示します; p)。

また、「memory_get_usage();」でphpdebug(sourceforgeをチェック)を打ち負かすことはできません。および「memory_get_peak_usage();」問題のある領域を見つけるため。


0

コードをステップ実行するときに変数の変化の値を監視できる統合デバッガーは、非常に優れています。ただし、サーバーでのソフトウェアのセットアップとクライアントでのある程度の構成が必要です。どちらも、正常に機能するために定期的なメンテナンスが必要です。

print_rは簡単に記述でき、どのような設定でも機能することが保証されています。


0

通常、ファイルに保存し、デバッグ情報を保存し、最終的には共通のフッターに再印刷できるカスタムログ関数を作成します。

共通の例外クラスをオーバーライドして、このタイプのデバッグを半自動化することもできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.