script - Wie debugge ich PHP-Skripte?




xdebug phpstorm (20)

phpdbg.com

Der Interactive Stepthrough PHP Debugger ist als SAPI-Modul implementiert und ermöglicht Ihnen die vollständige Kontrolle über die Umgebung, ohne die Funktionalität oder Leistung Ihres Codes zu beeinträchtigen. Es zielt darauf ab, eine leichtgewichtige, leistungsfähige, einfach zu bedienende Debugging-Plattform für PHP 5.4+ zu sein und wird mit PHP 5.6 ausgeliefert.

Eigenschaften beinhaltet:

  • Durchlauf-Debugging
  • Flexible Haltepunkte (Klassenmethode, Funktion, Datei: Zeile, Adresse, Opcode)
  • Einfacher Zugang zu PHP mit eingebautem eval ()
  • Einfacher Zugriff auf den aktuell ausgeführten Code
  • Benutzerland-API
  • SAPI Agnostic - Leicht integriert
  • PHP-Konfigurationsdatei-Unterstützung
  • JIT Super Globals - Setzen Sie Ihre eigenen !!
  • Optionale readline Unterstützung - Komfortabler Terminalbetrieb
  • Remote-Debugging-Unterstützung - Gebündelte Java-GUI
  • Einfache Operation

Siehe die Screenshots:

Homepage: phpdbg.com

PHP Error - Bessere Fehlerberichte für PHP

Dies ist eine sehr einfach zu benutzende Bibliothek (eigentlich eine Datei), um Ihre PHP-Skripte zu debuggen.

Das einzige, was Sie tun müssen, ist, eine Datei wie folgt einzuschließen (am Anfang Ihres Codes):

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

Dann geben Ihnen alle Fehler Informationen wie Backtrace, Code-Kontext, Funktionsargumente, Servervariablen usw. an. Beispiel:

Features sind:

  • trivial zu verwenden, es ist nur eine Datei
  • Fehler, die im Browser für normale und ajaxy-Anfragen angezeigt werden
  • AJAX-Anforderungen werden angehalten, sodass Sie sie automatisch erneut ausführen können
  • macht Fehler so streng wie möglich (fördert die Codequalität und tendiert dazu, die Leistung zu verbessern)
  • Code-Snippets über den gesamten Stack-Trace
  • bietet weitere Informationen (z. B. vollständige Funktionssignaturen)
  • behebt einige Fehlermeldungen, die einfach falsch sind
  • Satzstellung markieren
  • sieht gut aus!
  • Anpassung
  • manuell ein- und ausschalten
  • Führen Sie bestimmte Abschnitte ohne Fehlermeldung aus
  • Ignoriere Dateien, um zu vermeiden, Code in deinem Stack-Trace hervorzuheben
  • Anwendungsdateien; diese werden priorisiert, wenn ein Fehler auftritt!

Homepage: http://phperror.net/

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

Meine Gabel (mit zusätzlichen Fixes): https://github.com/kenorb-contrib/PHP-Error

DTrace

Wenn Ihr System DTrace dynamisches Tracing unterstützt (standardmäßig unter OS X installiert) und Ihr PHP mit den aktivierten DTrace-Probes ( --enable-dtrace ) kompiliert ist, kann dieser Befehl Ihnen helfen, PHP-Script im --enable-dtrace zu debuggen :

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

Also wenn der folgende Alias ​​in deine RC- Dateien ~/.bashrc wurde (zB ~/.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); }"'

Sie können Ihr Skript mit einem einfach zu merkenden Alias trace-php : trace-php .

Hier ist ein erweitertes dtrace-Skript, speichern Sie es einfach in dtruss-php.d , machen Sie es ausführbar ( chmod +x dtruss-php.d ) und führen chmod +x dtruss-php.d aus:

#!/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));
}

Homepage: dtruss-lamp bei GitHub

Hier ist einfache Verwendung:

  1. Führen Sie: sudo dtruss-php.d .
  2. Auf einem anderen Terminallauf: php -r "phpinfo();" .

Um das zu testen, können Sie mit der Datei index.php zu einem beliebigen Docroot gehen und den eingebauten PHP-Server ausführen durch:

php -S localhost:8080

Danach können Sie auf die Website unter http://localhost:8080/ zugreifen (oder wählen Sie den für Sie geeigneten Port). Von dort aus gelangen Sie auf einige Seiten, um die Trace-Ausgabe zu sehen.

Hinweis: Dtrace ist standardmäßig unter OS X verfügbar, unter Linux benötigen Sie wahrscheinlich dtrace4linux oder dtrace4linux Sie nach anderen alternatives .

Siehe: PHP und DTrace auf php.net verwenden

SystemTap

Alternativ können Sie nach SystemTap Tracing suchen, indem Sie das SystemTap SDT-Entwicklungspaket yum install systemtap-sdt-devel (z. B. yum install systemtap-sdt-devel ).

Hier finden Sie ein Beispielskript ( all_probes.stp ) zum Verfolgen aller zentralen statischen PHP-Prüfpunkte während der Laufzeit eines laufenden PHP-Skripts mit SystemTap:

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

Verwendung:

stap -c 'sapi/cli/php test.php' all_probes.stp

Siehe: Verwenden von SystemTap mit statischen PHP-DTrace-Probes auf php.net

Wie debugge ich PHP- Skripte?

Ich kenne grundlegendes Debugging wie das Error Reporting. Das Breakpoint-Debugging in PHPEclipse ist ebenfalls sehr nützlich.

Was ist die beste (in Bezug auf schnell und einfach) Möglichkeit, in PHPStorm oder einer anderen IDE zu debuggen?


+1 für print_r (). Verwenden Sie es, um den Inhalt eines Objekts oder einer Variablen auszugeben. Um es lesbarer zu machen, tun Sie es mit einem Pre-Tag, so dass Sie keine Quelle anzeigen müssen.

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

Auch var_dump ($ thing) - das ist sehr nützlich, um die Art der Subthings zu sehen


Das manuelle Debuggen ist für mich im Allgemeinen schneller - var_dump() und debug_print_backtrace() sind alle Werkzeuge, mit denen Sie Ihre Logik rüsten können.


Die Ausgabepufferung ist sehr nützlich, wenn Sie Ihre Ausgabe nicht durcheinander bringen wollen. Ich mache das in einem Einzeiler, den ich nach Belieben kommentieren kann

 ob_start();var_dump(); user_error(ob_get_contents()); ob_get_clean();

Die meisten Fehler lassen sich leicht finden, indem Sie einfach einige der wichtigsten Variablen var_dump , aber das hängt natürlich davon ab, welche Art von Anwendung Sie entwickeln.

Für komplexere Algorithmen sind die Step / Breakpoint / Watch Funktionen sehr hilfreich (wenn nicht notwendig)


Dies ist meine kleine Debug-Umgebung:

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

Für die wirklich grottenhaften Probleme, die zu zeitaufwendig wären, um print_r / echo zu verwenden, um herauszufinden, verwende ich die Debugging-Funktion meiner IDE (PhpEd). Im Gegensatz zu anderen IDEs, die ich verwendet habe, benötigt PhpEd ziemlich keine Einstellungen. Der einzige Grund, warum ich es nicht für irgendwelche Probleme benutze, ist, dass es schmerzhaft langsam ist. Ich bin mir nicht sicher, ob Langsamkeit spezifisch für PhpEd oder irgendeinen PHP-Debugger ist. PhpEd ist nicht kostenlos, aber ich glaube, es verwendet einen der Open-Source-Debugger (wie XDebug zuvor erwähnt) sowieso. Der Vorteil von PhpEd ist wiederum, dass es kein Setup benötigt, was ich in der Vergangenheit als ziemlich mühsam empfunden habe.



Ich benutze zend studio für Eclipse mit dem eingebauten Debugger. Es ist immer noch langsam im Vergleich zu Debugging mit Eclipse PDT mit Xdebug. Hoffentlich werden sie diese Probleme beheben, die Geschwindigkeit hat sich gegenüber den letzten Releases verbessert, aber das Überschreiten der Dinge dauert noch 2-3 Sekunden. Die Zend Firefox-Toolbar macht die Dinge wirklich einfach (debug nächste Seite, aktuelle Seite, etc.). Außerdem bietet es einen Profiler, der Ihren Code benchmarken und Tortendiagramme, Ausführungszeit usw. bereitstellen wird.



In einer Produktionsumgebung protokolliere ich relevante Daten mit error_log () im Fehlerprotokoll des Servers.


Je nach Problem mag ich eine Kombination von error_reporting (E_ALL) gemischt mit Echo-Tests (um die Zeile / Datei zu finden, in der der Fehler anfänglich aufgetreten ist; Sie wissen, dass nicht immer die Zeile / Datei php richtig ist?), IDE brace matching (um "Parse error: syntax error, unerwartete $ end" Probleme), und print_r (); Ausfahrt; Dumps (echte Programmierer sehen die Quelle; p).

Du kannst phpdebug (check sourceforge) auch nicht mit "memory_get_usage ();" und "memory_get_peak_usage ();" um die Problembereiche zu finden.


Normalerweise finde ich eine benutzerdefinierte Protokollfunktion, die in der Lage ist, eine Datei zu speichern, Debug-Informationen zu speichern und schließlich auf einer gemeinsamen Fußzeile neu zu drucken.

Sie können auch die allgemeine Exception-Klasse überschreiben, sodass diese Art des Debugging halbautomatisch ist.


Nun, bis zu einem gewissen Grad hängt es davon ab, wo die Dinge nach Süden gehen. Das ist das erste, was ich versuche zu isolieren, und dann verwende ich echo / print_r () wie nötig.

NB: Ihr wisst, dass ihr als zweites Argument für print_r () wahr werden könnt und es die Ausgabe zurückgibt, anstatt es zu drucken? Z.B:

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

PhpEd ist wirklich gut. Sie können in / über / aus Funktionen treten. Sie können Ad-hoc-Code ausführen, Variablen prüfen und Variablen ändern. Es ist erstaunlich.


PhpEdit hat einen eingebauten Debugger, aber normalerweise benutze ich echo (); und print_r (); der altmodische Weg !!


Um ehrlich zu sein, eine Kombination aus print und print_r (), um die Variablen auszudrucken. Ich weiß, dass viele andere fortgeschrittene Methoden bevorzugen, aber ich finde es am einfachsten zu verwenden.

Ich werde sagen, dass ich das nicht wirklich zu schätzen wusste, bis ich ein paar Microprocessor-Programme bei Uni gemacht habe und nicht einmal in der Lage war, dies zu verwenden.


Xdebug und das DBGp-Plugin für Notepad ++ für schwere Bugjagd, FirePHP für leichte Sachen. Schnell und dreckig? Nichts schlägt dBug .


XDebug ist essentiell für die Entwicklung. Ich installiere es vor jeder anderen Erweiterung. Es gibt Ihnen bei jedem Fehler Stack-Spuren und Sie können Profiling leicht aktivieren.

Verwenden Sie var_dump() für einen schnellen var_dump() über eine Datenstruktur. Verwenden Sie print_r() da Sie es mit <pre> und es nur jeweils eine var- print_r() .

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

Für eine echte Debugging-Umgebung ist das Beste, was ich gefunden habe, Komodo IDE, aber es kostet $$.


Xdebug , von Derick Rethans, ist sehr gut. Ich habe es vor einiger Zeit benutzt und fand es nicht so einfach zu installieren. Sobald Sie fertig sind, werden Sie nicht verstehen, wie Sie ohne es geschafft haben :-)

Es gibt einen guten Artikel über Zend Developer Zone (die Installation unter Linux scheint nicht einfacher) und sogar ein Firefox-Plugin , das ich nie benutzt habe.







xdebug