Kapitola 15. Zpracovßnφ chyb

V PHP existuje n∞kolik druh∙ chyb a varovßnφ. Jsou to:

Tabulka 15-1. Druhy chyb v PHP

HodnotaKonstantaPopisPoznßmka
1E_ERRORv²znamnΘ (fatßlnφ) runtimovΘ chyby 
2E_WARNINGruntimovß varovßnφ (nev²znamnΘ chyby) 
4E_PARSEkompilaΦnφ syntaktickΘ chyby 
8E_NOTICE runtimovΘ zprßvy (mΘn∞ vß╛nΘ ne╛ varovßnφ)  
16E_CORE_ERRORfatßlnφ chyby, kterΘ se vyskytly b∞hem startu PHPpouze PHP 4
32E_CORE_WARNINGvarovßnφ b∞hem startu PHPpouze PHP 4
64E_COMPILE_ERRORfatßlnφ kompilaΦnφ chybypouze PHP 4
128E_COMPILE_WARNINGkompilaΦnφ varovßnφ (nev²znamnΘ chyby)PHP 4 only
256E_USER_ERRORu╛ivatelsky generovanΘ chybovΘ zprßvyPHP 4 only
512E_USER_WARNINGu╛ivatelsky generovanß varovßnφPHP 4 only
1024E_USER_NOTICE u╛ivatelsky generovanΘ informativnφ zprßvyPHP 4 only
 E_ALLv╣echny z uveden²ch, kterΘ jsou danou verzφ PHP podporovßny 

V²╣e uvedenΘ hodnoty (a╗ ji╛ ΦφselnΘ nebo symbolickΘ) se pou╛φvajφ pro sestavenφ bitovΘ masky, kterß specifikuje, kterΘ chyby se majφ oznamovat. M∙╛ete pou╛φvat bitovΘ logickΘ operßtory pro kombinaci hodnot nebo maskovßnφ urΦit²ch druh∙ chyb. Uv∞domte si, ╛e v souboru php.ini budou sprßvn∞ interpretovßny pouze operßtory '|', '~', '!', a '&', a ╛e v php3.ini nelze pou╛φt ╛ßdnΘ z t∞chto operßtor∙.

V PHP 4 je jako implicitnφ hodnota pro error_reporting nastaveno E_ALL & ~E_NOTICE, tzn. hlß╣enφ v╣ech chyb a varovßnφ, kterΘ nejsou na ·rovni E_NOTICE. V PHP 3 je implicitnφ (E_ERROR | E_WARNING | E_PARSE), co╛ znamenß totΘ╛. Uv∞domte si, ╛e v souboru php3.ini nelze pou╛φvat konstanty, a proto nastavenφ error_reporting musφ b²t numerickΘ; tedy nap°φklad 7.

Inicißlnφ nastavenφ m∙╛e b²t v ini souboru zm∞n∞no direktivou error_reporting, v serveru Apache v souboru httpd.conf direktivou php_error_reporting (php3_error_reporting v PHP 3), a koneΦn∞ m∙╛e b²t tΘ╛ nastaveno skriptem za pou╛itφ funkce error_reporting().

Varovßnφ

Pokud upgradujete k≤d nebo server z PHP 3 na PHP 4, m∞li byste ov∞°it tato nastavenφ a volßnφ error_reporting() anebo potlaΦit hlß╣enφ nov²ch typ∙ chyb, zvlß╣t∞ E_COMPILE_ERROR. To m∙╛e vΘst k vyprßzdn∞nφ obsahu dokument∙ bez jakΘkoli informace o tom, co se stalo a kde hledat problΘm.

V╣echny PHP v²razy mohou b²t takΘ volßny s prefixem "@", kter² vypφnß hlß╣enφ chyb pro tento jedin² v²raz. Pokud b∞hem provßd∞nφ v²razu nastane chyba a volba track_errors je zapnutß, najdete chybovou zprßvu v globßlnφ prom∞nnΘ $php_errormsg.

Poznßmka: Prefixov²m operßtorem °φzenφ chyb @ nelze potlaΦit chybovß hlß╣enφ o syntaktick²ch chybßch.

Varovßnφ

V souΦasnosti prefixov² operßtor °φzenφ chyb v p°φpad∞ kritick²ch chyb (kterΘ ukonΦφ provßd∞nφ skriptu) pouze potlaΦφ chybovΘ hlß╣enφ. Jin²mi slovy, pokud pou╛ijete @ k potlaΦenφ chyb z jistΘ funkce, kterß nenφ dostupnß nebo byla chybn∞ zapsßna, skript zde skonΦφ, ani╛ by indikoval proΦ.

Nφ╛e uveden² p°φklad ukazuje pou╛itφ schopnostφ zpracovßnφ chyb v PHP. Definujeme funkci zpracovßnφ chyb, kterß zaznamenßvß informace do souboru (v XML formßtu) a v p°φpad∞ kritickΘ chyby ode╣le e-mailovou zprßvu v²vojß°i.

P°φklad 15-1. Pou╛itφ zpracovßnφ chyb ve skriptu

<?php
// ud∞lßme si vlastnφ zpacovßnφ chyb
error_reporting(0);

// u╛ivatelsky definovanß funkce pro zpracovßnφ chyb
function userErrorHandler ($errno, $errmsg, $filename, $linenum, $vars) {
    // ΦasovΘ razφtko polo╛ky
    $dt = date("Y-m-d H:i:s (T)");

    // definuje asociativnφ pole pro chybov² °et∞zec
    // ve skuteΦnosti mohou polo╛ky obsahovat pouze
    // hodnoty 2,8,256,512 a 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"
                );
    // mno╛ina chyb, pro kterΘ bude ulo╛en v²pis prom∞nn²ch
    $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";
    
    // pro testovßnφ
    // echo $err;

    // ulo╛ do chybovΘho protokolu a po╣li mi zprßvu (pokud je to kritickß chyba)
    error_log($err, 3, "/usr/local/php4/error.log");
    if ($errno == E_USER_ERROR)
        mail("phpdev@mydomain.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");

// nedefinovanß konstanta, generuje varovßnφ
$t = I_AM_NOT_DEFINED;

// definuje n∞jakΘ "vektory"
$a = array(2,3,"foo");
$b = array(5.5, 4.3, -1.6);
$c = array (1,-3);

// generuje u╛ivatelskou chybu
$t1 = distance($c,$b)."\n";

// generuje jinou u╛ivatelskou chybu
$t2 = distance($b,"i am not an array")."\n";

// generuje hlß╣enφ
$t3 = distance($a,$b)."\n";

?>
Toto je pouze jednoduch² p°φklad, kter² ukazuje, jak pou╛φvat Funkce pro zpracovßnφ a zßznam chyb.

Viz takΘ error_reporting(), error_log(), set_error_handler(), restore_error_handler(), trigger_error(), user_error()