getTraceAsString()
PHP getTraceAsString()-Methode: Rückgabe des Stack-Trace einer Exception als String, Ausgabe lesen und protokollieren.
Was getTraceAsString() macht
getTraceAsString() ist eine Methode, die für jede PHP-Exception verfügbar ist (jede Klasse,
die Throwable implementiert — Exception, Error und ihre Unterklassen). Sie gibt den
Stack-Trace zurück — die Kette von Funktions- und Methodenaufrufen, die zum Zeitpunkt des
Werfens der Exception aktiv waren — formatiert als einzelner, menschenlesbarer String.
Der Stack-Trace beantwortet die Frage „Wie ist die Ausführung hierher gelangt?" Wenn etwas
tief im Code geworfen wird, teilt die Nachricht allein (getMessage()) mit, was schief
gelaufen ist, aber der Trace zeigt den genauen Aufrufpfad, der dazu geführt hat. Das macht ihn
zur nützlichsten Information beim Debuggen eines Fehlers, der sich nicht leicht reproduzieren lässt.
getTraceAsString() ist die String-Version von getTrace(), die
dieselben Informationen als strukturiertes Array zurückgibt. Verwenden Sie getTrace(), wenn
einzelne Frames programmatisch untersucht werden sollen; verwenden Sie getTraceAsString(),
wenn Sie etwas protokollieren oder ausgeben möchten.
Syntax
public Throwable::getTraceAsString(): stringEs werden keine Argumente übergeben und die Methode ist final in den Basisklassen Exception
und Error, gibt also immer PHPs Standard-Trace-Format zurück. Sie wird auf einem gefangenen
Exception-Objekt innerhalb eines catch-Blocks aufgerufen:
<?php
try {
// Code that may throw an exception
} catch (Throwable $e) {
$trace = $e->getTraceAsString();
}Das Fangen von Throwable (anstatt nur Exception) bedeutet, dass auch Error-Objekte wie
TypeError und DivisionByZeroError behandelt werden. Siehe das Kapitel
Exception für die vollständige Hierarchie.
Ein vollständiges, ausführbares Beispiel
Dieses Skript wirft eine Exception zwei Ebenen tief, sodass Sie sehen können, wie der Trace-String tatsächlich aussieht:
<?php
function loadUser(int $id): array
{
throw new InvalidArgumentException("No user with id $id");
}
function handleRequest(): void
{
loadUser(42);
}
try {
handleRequest();
} catch (Throwable $e) {
echo $e->getTraceAsString();
}Ausgabe:
#0 /app/index.php(10): loadUser(42)
#1 /app/index.php(14): handleRequest()
#2 {main}Die Ausgabe lesen
Jede Zeile ist ein Frame im Call-Stack, beginnend mit dem innersten:
#0,#1, … — die Frame-Nummer.#0ist der Aufruf, der beim Werfen der Exception aktiv war; höhere Nummern sind die darüber liegenden Aufrufer./app/index.php(10)— die Datei und Zeilennummer der Aufrufstelle.loadUser(42)— die aufgerufene Funktion oder Methode mit ihren Argumenten. Lange String-Argumente werden abgeschnitten (z. B.'/etc/app/missin...'), um den Trace lesbar zu halten.#2 {main}— der spezielle letzte Frame, der das Top-Level-Skript (den globalen Scope) markiert.
Die Throw-Stelle selbst (die genaue Datei und Zeile, wo throw ausgeführt wurde) ist nicht
in diesem String enthalten — sie befindet sich in getFile() und
getLine().
Beispiele
Beispiel 1: Den Trace in eine Datei protokollieren
In der Produktion möchte man einen Trace selten dem Benutzer anzeigen — er wird für spätere Analyse protokolliert. Kombinieren Sie Nachricht, Datei und Zeile mit dem Trace für einen vollständigen Eintrag:
<?php
try {
// Code that may throw an exception
} catch (Throwable $e) {
$entry = sprintf(
"[%s] %s in %s:%d\n%s\n\n",
date('Y-m-d H:i:s'),
$e->getMessage(),
$e->getFile(),
$e->getLine(),
$e->getTraceAsString()
);
file_put_contents('/path/to/app.log', $entry, FILE_APPEND | LOCK_EX);
}LOCK_EX verhindert, dass zwei gleichzeitige Anfragen ihre Log-Einträge vermischen. Für echte
Anwendungen ist eine Logging-Bibliothek wie Monolog vorzuziehen, aber die zugrunde liegenden
Daten sind derselbe String, den Sie hier erhalten.
Beispiel 2: Den Trace im Browser anzeigen (nur in der Entwicklung)
Beim lokalen Arbeiten kann es praktisch sein, den Trace direkt auf der Seite auszugeben. Wickeln
Sie ihn in <pre> ein, damit Zeilenumbrüche erhalten bleiben, und escapen Sie ihn, damit
Trace-Inhalte kein HTML einschleusen können:
<?php
try {
// Code that may throw an exception
} catch (Throwable $e) {
echo '<pre>' . htmlspecialchars($e->getTraceAsString()) . '</pre>';
}Zeigen Sie Traces niemals Endbenutzern in der Produktion an — sie enthüllen Dateipfade, Code-Strukturen und manchmal Argumentwerte, die Angreifern helfen. Schützen Sie dies hinter einer Umgebungsprüfung.
Beispiel 3: Den Trace beim Weiterwerfen erhalten
Wenn Sie eine Low-Level-Exception abfangen und eine aussagekräftigere weiterwerfen, übergeben Sie die ursprüngliche als previous-Exception, damit ihr Trace nicht verloren geht:
<?php
try {
// some database call that throws PDOException
} catch (PDOException $e) {
throw new RuntimeException('Could not load the report', 0, $e);
}Die neue RuntimeException hat ihren eigenen Trace, während
getPrevious() die ursprüngliche Exception (und ihr
getTraceAsString()) zurückgibt. PHPs Standard-Handler für nicht abgefangene Exceptions gibt
beide, verkettet, aus.
Häufige Fallstricke
- Der Trace beschreibt den Wurf-Punkt, nicht den Fang-Punkt. Er wird im Moment der
Exception-Erstellung fixiert, daher zeigt ein späteres
getTraceAsString()immer den Ursprungsort der Exception, nicht den Ort der Behandlung. - Argumente können abgeschnitten oder ausgeblendet werden. Lange Strings werden gekürzt;
wenn die INI-Einstellung
zend.exception_ignore_argsaktiviert ist (Standard in vielen Produktivumgebungen), werden Argumentwerte aus Sicherheitsgründen vollständig weggelassen. - Es wird ein String zurückgegeben, niemals
null. Selbst für eine Exception, die auf Top-Level geworfen wurde, erhält man mindestens den Frame#0 {main}.
Verwandte Methoden
getTrace()— dieselben Daten als strukturiertes Array.getMessage()— die menschenlesbare Fehlermeldung.getCode()— der numerische Code der Exception.getPrevious()— die verknüpfte vorherige Exception.set-exception-handler()— nicht abgefangene Exceptions global behandeln.
Fazit
getTraceAsString() wandelt den Call-Stack einer Exception in einen kompakten, protokollierbaren
String um und ist damit eines der wertvollsten Werkzeuge zur Fehlerdiagnose in PHP. Kombinieren
Sie es mit getMessage(), getFile() und getLine(), um ein vollständiges Bild jedes Fehlers
zu erfassen, protokollieren Sie es statt es in der Produktion Benutzern anzuzeigen, und erhalten
Sie die Kette mit getPrevious() beim Weiterwerfen.