16. Fejezet. Hibakezelés

A hibáknak és figyelmeztetéseknek PHP-ben számos típusa van. Ezek:

Táblázat 16-1. PHP hiba típusok

ÉrtékSzimbólumLeírásMegjegyzés
1E_ERRORfatális futás-idejű hibák 
2E_WARNINGnem fatális futás-idejű hibák 
4E_PARSEfordítás-idejű feldolgozási hibák 
8E_NOTICEfutás-idejű figyelmeztetések (a notice a warning-nál gyengébb) 
16E_CORE_ERRORfatális hibák, amik a PHP elindulásakor lépnek felcsak a PHP 4-ben
32E_CORE_WARNINGnem fatális hibák figyelmeztetései (warning), amik a PHP elindulásakor lépnek felcsak a PHP 4-ben
64E_COMPILE_ERRORfatális fordítás-idejű hibákcsak a PHP 4-ben
128E_COMPILE_WARNINGnem fatális fordítás-idejű figyelmeztetések (warning)csak a PHP 4-ben
256E_USER_ERRORfelhasználó által generált hibaüzenetekcsak a PHP 4-ben
512E_USER_WARNINGfelhasználó által generált figyelmeztetések (warning)csak a PHP 4-ben
1024E_USER_NOTICEfelhasználó által generált figyelmeztetések (notice)csak a PHP 4-ben
 E_ALLaz összes fent felsorolt elemcsak a PHP 4-ben

A fenti értékek (akár a numerikusak, akár a szimbolikusak) arra használhatóak, hogy felépíts egy bitmask-ot, ami megadja, hogy mely hibákat kell jeleznie a PHP-nek. Használhatod bitszintű operátorokat, hogy összeállítsd a fenti elemekből a neked megfelelő értéket, vagy letilts egyes hibákat. Csak a '|', '~', '!', és '&' operátorok használhatóak php.ini fájlban, és semmilyen operátor sem használható a php3.ini fájlban.

PHP 4-ben az alapbeállítású error_reporting érték E_ALL & ~E_NOTICE, ami azt jelenti, hogy minden hiba és figyelmeztetés megjelenik az E_NOTICE-szint kivételével. PHP 3-ban az alapbeállítás (E_ERROR | E_WARNING | E_PARSE), ugyanezt jelenti. Vedd figyelembe, hogy ezek a konstansok nem támogatottak a PHP 3 php3.ini fájljában, ezért az error_reporting beállítás a numerikus 7 érték.

Ezek a beállítások az ini fájl error_reporting direktívájával változtathatóak meg, vagy az Apache httpd.conf fájlban a php_error_reporting (php3_error_reporting PHP 3 esetén) direktívával vagy végül futásidőben egy szkriptben az error_reporting() függvénnyel.

Figyelem

Ha a kódod vagy a szervered frissíted PHP 3-ról PHP 4-re, jól teszed, ha ellenőrzöd ezeket a beállításokat és az error_reporting() függvényhívásokat, különben akaratlanul kikapcsolod az új hibatípusokat, különösen az E_COMPILE_ERROR-t. Ez üres dokumentumokhoz vezethet, amik nem tartalmaznak semmilyen utalást arra, hogy mi történt, vagy hogy hol kellene keresni a problémát...

Minden PHP kifejezés írható a "@" előtaggal, ami kikapcsolja a hibajelentést arra a kifejezésre. Ha hiba lép fel a kifejezés kiértékelésekor, és a track_errors szolgáltatás be van kapcsolva, a hibaüzenet megtalálható a $php_errormsg globális változóban.

Megjegyzés: A @ hibakezelő operátor nem kapcsolja ki a szkriptek feldolgozása során előforduló hibák (parse error) jelentését.

Figyelem

Jelenleg a "@" hibakezelő operátor kikapcsolja azon kritikus hibák jelentését is, amik megállítják a szkript futását. Más problémák mellett, ha egy függvényből érkező hibaüzenetek elnyelésére használod a "@" jelet, meg fog állni a szkript futása, ha nem létezik a megadott függvény, vagy elírtad a nevét.

Az alábbiakban láthatsz egy példát a PHP hibakezelő képességeire. Definiálunk egy hibakezelő függvényt, ami tárolja a hibákat egy fájlba (XML formátummal) és email-t küld a fejlesztőnek ha a programban kritikus hiba történik.

Példa 16-1. Hibakezelés használata egy szkriptben

<?php
// saját hibakezelést építünk
error_reporting(0);

// felhasználó által definiált hibakezelő függvény
function sajatHibaKezelo ($hibaszam, $hibauzenet, $filenev, $sorszam, $valtozok) {

    // időbélyeg a hibához
    $ido = date("Y-m-d H:i:s (T)");

    // Asszociatív tömb definiálása a hibaszövegeknek.
    // Valójában csak a 2,8,256,512 és 1024 elemeket
    // vesszük figyelembe
    $hibatipus = 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"
                );

    // azok a hibatípusok, amikre a változókat is el kell menteni
    $user_hibak = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
    
    $hiba = "<errorentry>\n";
    $hiba .= "\t<datetime>".$ido."</datetime>\n";
    $hiba .= "\t<errornum>".$hibaszam."</errornum>\n";
    $hiba .= "\t<errortype>".$hibatipus[$hibaszam]."</errortype>\n";
    $hiba .= "\t<errormsg>".$hibauzenet."</errormsg>\n";
    $hiba .= "\t<scriptname>".$filenev."</scriptname>\n";
    $hiba .= "\t<scriptlinenum>".$sorszam."</scriptlinenum>\n";

    if (in_array($hibaszam, $user_hibak))
        $hiba .= "\t<vartrace>".wddx_serialize_value($valtozok,"Variables")."</vartrace>\n";
    $hiba .= "</errorentry>\n\n";
    
    // teszteléshez
    // echo $hiba;

    // a hibanapló elmentése, email küldés ha kritikus hiba van
    error_log($hiba, 3, "/usr/local/php4/error.log");
    if ($hibaszam == E_USER_ERROR)
        mail("phpdev@example.com","Kritikus programhiba",$hiba);
}


function tavolsag ($vektor1, $vektor2) {
    if (!is_array($vektor1) || !is_array($vektor2)) {
        trigger_error("Helytelen parameterek, tomboket varok", E_USER_ERROR);
        return NULL;
    }

    if (count($vektor1) != count($vektor2)) {
        trigger_error("A vektorok ugyanolyan dimenziojuak legyenek", E_USER_ERROR);
        return NULL;
    }

    for ($i=0; $i<count($vektor1); $i++) {
        $c1 = $vektor1[$i]; $c2 = $vektor2[$i];
        $d = 0.0;
        if (!is_numeric($c1)) {
            trigger_error("Az elso vektor $i koordinataja nem szam, nullaval szamolok", 
                            E_USER_WARNING);
            $c1 = 0.0;
        }
        if (!is_numeric($c2)) {
            trigger_error("A masodik vektor $i koordinataja nem szam, nullaval szamolok", 
                            E_USER_WARNING);
            $c2 = 0.0;
        }
        $d += $c2*$c2 - $c1*$c1;
    }
    return sqrt($d);
}

$regi_hiba_kezelo = set_error_handler("sajatHibaKezelo");

// nem definiált konstans, warning-ot generál
$t = NEM_VAGYOK_DEFINIALVA;

// néhány "vektor" definiálása
$a = array (2,3, "ize");
$b = array (5.5, 4.3, -1.6);
$c = array (1, -3);

// user hiba generálása
$t1 = tavolsag($c, $b)."\n";

// újabb user hiba generálása
$t2 = tavolsag($b, "ez nem tömb")."\n";

// warning generálása
$t3 = tavolsag($a, $b)."\n";
?>
Ez csak egy egyszerű példa, ami bemutatja, hogy hogyan kell használni a Hibakezelő és naplózó függvényeket.

Lásd még: error_reporting(), error_log(), set_error_handler(), restore_error_handler(), trigger_error(), és user_error().