Hoofdstuk 15. Fout afhandeling

Er zijn verschillende types fouten en waarschuwingen in PHP, namelijk:

Tabel 15-1. PHP fout types

WaardeConstanteOmschrijvingOpmerking
1E_ERRORfatale run-time fouten 
2E_WARNINGrun-time waarschuwingen (niet fatale fouten) 
4E_PARSEcompile-time parse errors 
8E_NOTICE run-time opmerkingen (minder belangrijk dan waarschuwingen)  
16E_CORE_ERRORfatale fouten die gebeuren terwijl PHP opstartalleen in PHP 4
32E_CORE_WARNING waarschuwingen (niet fatale fouten) die gegeven worden terwijl PHP opstart alleen in PHP 4
64E_COMPILE_ERRORfatale compile-time foutalleen in PHP 4
128E_COMPILE_WARNINGcompile-time waarschuwingen (niet fatale fouten)alleen in PHP 4
256E_USER_ERRORuser-generated error messagePHP 4 only
512E_USER_WARNINGdoor de gebruiker gegenereerde waarschuwingalleen in PHP 4
1024E_USER_NOTICE door de gebruiker gegenereerde opmerkingalleen in PHP 4
 E_ALLalle bovenstaande, indien ondersteunt 

De bovenstaande waarden (zowel numeriek of symbolisch) worden gebruikt om een bitmask te maken dat aangeeft welke errors er gemeld moeten worden. Je kunt bitwise operators gebruiken om waarden toe te voegen ofwel te verwijderen uit het bitmask. Let op: alleen '|', '~', '!' en '&' worden ondersteund in php.ini, maar er worden helemaal geen bitwise operatoren ondersteund in php3.ini

In PHP 4 is de standaard error_reporting instelling E_ALL & ~E_NOTICE. Dit betekend dat alle foutmeldingen/waarschuwingen gemeld worden tenzij deze een E_NOTICE is. In PHP 3 is de standaard instelling (E_ERROR | E_WARNING | E_PARSE), wat precies hetzelfde betekend. Let op: gezien het feit dat constanten niet ondersteund worden in PHP 3's php3.ini de error_reporting, moet de instelling numeriek of wel 7 zijn.

De standaard instelling kan worden veranderd in het .ini bestand met het error_reporting directive, in je Apache httpd.conf bestand kan dit gedaan worden met het php_error_reporting (php3_error_reporting for PHP3) directive en als laatste kan het ook run-time gewijzigd worden met de error_reporting() functie.

Waarschuwing

Als je code of servers upgrade van PHP 3 naar PHP 4 moet je controleren of deze instellingen en/of aanroepen naar de error_reporting() juist zijn. Als je dit niet doet dan kan het zijn dat belangrijke nieuwe fout types zoals E_COMPILE_ERROR niet gebruikt kunnen worden. Dit kan leiden tot een leeg resultaat document zonder enige informatie over wat er fout is gegegaan.

Alle PHP expressies kunnen aangeroepen met de '@' prefix. Dit zorgt er voor dat mocht er een fout optreden in deze expressie deze niet gemeld word. Als er een fout optreedt in een expressie en de track_errors mogelijkheid word gebruikt, kun je de foutmelding in de globale variable $php_errormsg.

Waarschuwing

Op het moment meld de @ error-control operator prefix zelfs geen fatale fouten die het script beëindigen. Dit betekent onder andere dat als je @ gebruikt om foutmeldingen te onderdrukken op een functie die niet bestaat of fout getypt is, het script zal stoppen zonder enige indicatie van waarom het misgegaan is.

Hieronder staat een voorbeeld over hoe je de error handling mogelijkheden in PHP kunt gebruiken. We definieëren een error handling functie die fout informatie naar een bestand logt gebruik makend van een XML formaat. Mocht er een kritieke fout optreden dan wordt de ontwikkelaar een emailtje gestuurd.

Voorbeeld 15-1. Gebruik van error handling in PHP


<?php
// We regelen onze eigen fout rapportage.
error_reporting(0);

// Onze eigen error handler
function userErrorHandler ($errno, $errmsg, $filename, $linenum, $vars) {
    // timestamp voor de log entry
    $dt = date("Y-m-d H:i:s (T)");

    // definieër een associatieve array met mogelijk fouten
    // in realiteit zouden we alleen kijken naar de fouten
    // 2,8,256,512 en 1024

    $fouttype = array (
                1   =>  "Fout",
                2   =>  "Waarschuwing",
                4   =>  "Parsing Fout",
                8   =>  "Opmerking",
                16  =>  "Interne Fout",
                32  =>  "Interne Waarschuwing",
                64  =>  "Compile Fout",
                128 =>  "Compile Waarschuwing",
                256 =>  "Gebruikers Error",
                512 =>  "Gebruikers Waarschuwing",
                1024=>  "Gebruikers Opmerking"
                );
    // Lijst van errors waar we de variable voor loggen.
    $gebruikers_fouten = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
    
    $err = "<foutentry>\n";
    $err .= "\t<datumtijd>".$dt."</datumtijd>\n";
    $err .= "\t<foutnum>".$errno."</foutnum>\n";
    $err .= "\t<fouttype>".$fouttype[$errno]."</fouttype>\n";
    $err .= "\t<foutmsg>".$errmsg."</foutmsg>\n";
    $err .= "\t<scriptnaam>".$filename."</scriptnaam>\n";
    $err .= "\t<scriptlinenum>".$linenum."</scriptlinenum>\n";

    if (in_array($errno, $gebruikers_errors))
        $err .= "\t<vartrace>".wddx_serialize_value($vars,"Variablen")."</vartrace>\n";
    $err .= "</foutentry>\n\n";
    
    // for testing
    // echo $err;

    // Sla de log op, en e-mail me als er een kritieke fout optreed
    error_log($err, 3, "/usr/local/php4/error.log");
    if ($errno == E_USER_ERROR)
        mail("phpdev@mydomain.com","Kritieke fout opgetreden!",$err);
}


function afstand ($vect1, $vect2) {
    if (!is_array($vect1) || !is_array($vect2)) {
        trigger_error("Incorrecte parameters, arrays verwacht", E_USER_ERROR);
        return NULL;
    }

    if (count($vect1) != count($vect2)) {
        trigger_error("Vectoren moeten gelijk aantal elementen hebben", 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("Coordinaat $i in vector 1 is geen numerieke waarde, nul wordt gebruikt", 
                            E_USER_WARNING);
            $c1 = 0.0;
        }
        if (!is_numeric($c2)) {
            trigger_error("Coordinaat $i in vector 2 is geen numerieke waarde, nul wordt gebruikt", 
                            E_USER_WARNING);
            $c2 = 0.0;
        }
        $d += $c2*$c2 - $c1*$c1;
    }
    return sqrt($d);
}

$oude_error_handler = set_error_handler("userErrorHandler");

// niet gedefinieërde constante, er wordt een waarschuwing gegeven
$t = I_AM_NOT_DEFINED;

// defineer een paar "vectoren"
$a = array(2,3,"foo");
$b = array(5.5, 4.3, -1.6);
$c = array (1,-3);

// genereer een fout
$t1 = distance($c,$b)."\n";

// genereer nog fout
$t2 = distance($b,"ik ben geen array")."\n";

// genereer een waarschuwing
$t3 = distance($a,$b)."\n";

?>
    
Dit is slechts een simpel voorbeeld wat laat zien hoe je de Error Handling en Logging functies kan gebruiken.

Zie ook: error_reporting(), error_log(), set_error_handler(), restore_error_handler(), trigger_error(), user_error()