Kapitel 16. Fehlerbehandlung

Es gibt verschiedene Arten von Fehlermeldungen und Warnungen in PHP. Diese sind:

Tabelle 16-1. PHP Fehlertypen

WertKonstanteBeschreibungBemerkung
1E_ERRORSchwere Laufzeitfehler 
2E_WARNINGLaufzeit-Warnungen (keine schweren Fehler) 
4E_PARSEFehler beim Parsen während des Kompilierens 
8E_NOTICE Mitteilungen zur Laufzeit (weniger ernst als Warnungen)  
16E_CORE_ERRORSchwere Fehler während dem Start von PHPNur PHP 4
32E_CORE_WARNING Warnungen (keine schweren Fehler) während dem Start von PHP Nur PHP 4
64E_COMPILE_ERRORSchwere Fehler während des KompilierensNur PHP 4
128E_COMPILE_WARNINGWarnungen (keine schweren Fehler) während des KompilierensNur PHP 4
256E_USER_ERRORVom Benutzer erzeugte FehlermeldungNur PHP 4
512E_USER_WARNINGVom Benutzer erzeugte WarnungNur PHP 4
1024E_USER_NOTICE Vom Benutzer erzeugte MitteilungenNur PHP 4
 E_ALLAlle der oben genannten, welche unterstützt werden 

Aus den obigen Werten (numerisch oder symbolisch) wird eine Bitmaske erstellt, welche die zu meldenden Fehler angibt. Sie können die Bit-Operatoren verwenden um diese Werte zu kombinieren, oder um bestimmte Fehlertypen auszunehmen. Beachten Sie, dass innerhalb der php.ini nur '|', '~', '!', und '&' erkannt werden, und dass innerhalb der php3.ini keine Bit-Operatoren möglich sind.

In PHP 4 ist die Standardeinstellung für error_reporting E_ALL & ~E_NOTICE, d.h. es werden abgesehen vom E_NOTICE-Level alle Fehler und Warnungen angezeigt. In PHP 3 ist die Standardeinstellung (E_ERROR | E_WARNING | E_PARSE), was das gleiche bedeutet. Beachten Sie, dass in der php3.ini von PHP 3 keine Konstanten unterstützt werden, d.h. die Einstellungen von error_reporting müssen numerisch angegeben werden, in diesem Fall 7.

Die Anfangseinstellung kann in der ini Datei mittels der error_reporting Direktive, sowie in Ihrer Apache httpd.conf Datei mittels der php_error_reporting (php3_error_reporting in PHP 3) Direktive geändert werden. Sie kann aber auch während der Laufzeit innerhalb eines Skriptes mittels der Funktion error_reporting() gesetzt werden.

Warnung

Während eines Upgrades Ihres Codes oder Servers von PHP 3 auf PHP 4 sollten Sie diese Einstellungen und Aufrufe von error_reporting() kontrollieren, sonst könnten Sie die Meldung neuer Fehlertypen, speziell E_COMPILE_ERROR, deaktivieren. Dies könnte dazu führen, dass Sie ein leeres Dokument ohne jeden Hinweis auf die Ursache des Problems erhalten.

Alle PHP Ausdrücke können auch mit dem Präfix "@" aufgerufen werden, welches Fehlermeldungen für diesen bestimmten Ausdruck deaktiviert. Ist während solch einem Ausdruck ein Fehler aufgetreten und track_errors aktiviert, finden Sie diese Fehlermeldung in der globalen Variable $php_errormsg.

Anmerkung: Der @ Fehler-Kontroll-Operator verhindert jedoch keine Meldungen, welche aus Fehlern beim Parsen resultieren.

Warnung

Derzeit deaktiviert der @ Fehler-Kontroll-Operator auch Meldungen von kritischen Fehlern, welche die Ausführung des Skriptes abbrechen. Unter anderem heißt das, dass wenn Sie @ zur Unterdrückung von Fehlermeldungen einer bestimmten Funktion verwenden, im Falle des Fehlens der Funktion bzw. eines Tippfehlers die Ausführung des Skriptes genau dort ohne Anzeichen warum abgebrochen.

Nachstehend finden Sie ein Beispiel für die Verwendung der Möglichkeiten zur Fehlerbehandlung in PHP. Wir definieren eine Funktion zur Fehlerbehandlung, welche die Information in eine Datei schreibt (im XML Format), und im Falle von schweren Fehlern in der Logik dem Entwickler ein E-Mail sendet.

Beispiel 16-1. Verwenden der Fehlerbehandlung in einem Skript

<?php
// wir machen uns die Fehlerbehandlung selbst
error_reporting(0);

// Benutzerdefinierte Funktion zur Fehlerbehandlung
function userErrorHandler ($errno, $errmsg, $filename, $linenum, $vars) {
    // timestamp für den Fehlereintrag
    $dt = date("Y-m-d H:i:s (T)");

    // definiere ein assoziatives Array mit Fehler String
    // in der Realität sind die einzigen zu bedenkenden
    // Einträge 2,8,256,512 und 1024
    $errortype = array (
                1   =>  "Error",
                2   =>  "Warning",
                4   =>  "Parsing Error",
                8   =>  "Notice",
                16  =>  "Core Error",
                32  =>  "Core Warning",
                64  =>  "Compile Error",
                128 =>  "Compile Warning",
                256 =>  "User Error",
                512 =>  "User Warning",
                1024=>  "User Notice"
                );
    // Gruppe von Fehlern, die zur Nachverfolgung gespeichert werden
    $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
    
    $err = "<errorentry>\n";
    $err .= "\t<datetime>".$dt."</datetime>\n";
    $err .= "\t<errornum>".$errno."</errornum>\n";
    $err .= "\t<errortype>".$errortype[$errno]."</errortype>\n";
    $err .= "\t<errormsg>".$errmsg."</errormsg>\n";
    $err .= "\t<scriptname>".$filename."</scriptname>\n";
    $err .= "\t<scriptlinenum>".$linenum."</scriptlinenum>\n";

    if (in_array($errno, $user_errors))
        $err .= "\t<vartrace>".wddx_serialize_value($vars,"Variables")."</vartrace>\n";
    $err .= "</errorentry>\n\n";
    
    // zum Testen
    // echo $err;

    // in das Log speichern, und im Falle eines kritischen Fehlers E-Mail an mich
    error_log($err, 3, "/usr/local/php4/error.log");
    if ($errno == E_USER_ERROR)
        mail("phpdev@example.com","Critical User Error",$err);
}


function distance ($vect1, $vect2) {
    if (!is_array($vect1) || !is_array($vect2)) {
        trigger_error("Incorrect parameters, arrays expected", E_USER_ERROR);
        return NULL;
    }

    if (count($vect1) != count($vect2)) {
        trigger_error("Vectors need to be of the same size", E_USER_ERROR);
        return NULL;
    }

    for ($i=0; $i<count($vect1); $i++) {
        $c1 = $vect1[$i]; $c2 = $vect2[$i];
        $d = 0.0;
        if (!is_numeric($c1)) {
            trigger_error("Coordinate $i in vector 1 is not a number, using zero", 
                            E_USER_WARNING);
            $c1 = 0.0;
        }
        if (!is_numeric($c2)) {
            trigger_error("Coordinate $i in vector 2 is not a number, using zero", 
                            E_USER_WARNING);
            $c2 = 0.0;
        }
        $d += $c2*$c2 - $c1*$c1;
    }
    return sqrt($d);
}

$old_error_handler = set_error_handler("userErrorHandler");

// undefinierte Konstante, generiert eine Warnung
$t = I_AM_NOT_DEFINED;

// definiere einige "Vektoren"
$a = array(2,3,"foo");
$b = array(5.5, 4.3, -1.6);
$c = array (1,-3);

// generiere einen Benutzerfehler
$t1 = distance($c,$b)."\n";

// generiere einen weiteren Benutzerfehler
$t2 = distance($b,"i am not an array")."\n";

// generiere eine Warnung
$t3 = distance($a,$b)."\n";

?>
Dies ist nur ein einfaches Beispiel für die Verwendung der Error Handling and Logging functions.

Siehe auch error_reporting(), error_log(), set_error_handler(), restore_error_handler(), trigger_error(), user_error()