Stacktraces in PHP zur Fehlersuche


Manchmal steht man mit PHP vor dem Problem dass ein Fehler geworfen wird, man aber nicht so genau weiß wie es dazu kam.

Hierfür gibt es eine recht elegante Lösung um den Ablauf zurückzuverfolgen.

Mithilfe der PHP Exception-Klasse lässt sich der Stacktrace als String zurückgeben.

<?php 
/** 
 * @return object 
 */
function getStackTrace() {
    $e = new Exception();
    $trace = explode( "\n", $e->getTraceAsString() );
    // Array umkehren damit der zeitliche Ablauf stimmt
    $trace = array_reverse( $trace );
    array_shift( $trace ); // Entferne {main}
    array_pop( $trace ); // Diesen Funktionsaufruf entfernen
    $result = array();
    foreach( $trace as $call ) {
        if( stristr( $call, 'internal function' ) ) {
            continue; // Interne Funktionen ausblenden
        }
        // Alle Pfadangaben bis zum Dateinamen entfernen
        $result[] = preg_replace( '°(.*)[\\\/]°si', '', $call );
    }
    // Als Objekt zurückgeben damit man es evtl. mit FirePHP loggen kann
    return (object) $result;
}

//Klassen zum Testen
class A
{
    public function test()
    {
        $B = new B;
        return $B->test();
    }
}

class B
{
    public function test()
    {
        $C = new C;
        return $C->test();
    }
}

class C
{
    public function test()
    {
        trigger_error( 'Nested calls', E_USER_ERROR );
        return 'C';
    }
}
//Den Error-Handler setzen
set_error_handler( function () {
    echo '<pre>';
    print_r( getStackTrace() );
} );
$A = new A;
$A->test();
 

Das ergibt folgende Ausgabe:

stdClass Object
(
    [0] => test.php(57): A->test()
    [1] => test.php(30): B->test()
    [2] => test.php(39): C->test()
    [3] => test.php(47): trigger_error('Nested calls', 256)
)

Somit lässt sich relativ gut der Ablauf bis zum Fehler nachverfolgen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.