Bölüm 15. Hata İşlemleri

PHP'de pek çok uyarı çeşidi vardır. Bunlar:

Tablo 15-1. PHP uyarı çeşitleri

DeğerSabitTanımNot
1E_ERRORhayati çalışma hataları 
2E_WARNINGçalışma uyarıları (hayati olmayan hatalar) 
4E_PARSEderleme sırasında ayrıştırma hataları 
8E_NOTICE çalışma sırasındaki bildirimler (uyarılardan daha az önemli)  
16E_CORE_ERRORPHP'nin iç yapısıyla ilgili, başlatılmasını engelleyen hayati hatalarsadece PHP 4
32E_CORE_WARNING PHP'nin iç yapısıyla ilgili, başlatılması ile ilgili uyarılar (hayati olmayan hatalar) sadece PHP 4
64E_COMPILE_ERRORhayati derleme hatalarıSadece PHP 4
128E_COMPILE_WARNINGderleme sırasındaki uyarılar (hayati olmayan hatalar)sadece PHP 4
256E_USER_ERRORkullanıcının yarattığı hata mesajısadece PHP 4
512E_USER_WARNINGkullanıcının yarattığı uyarı mesajısadece PHP 4
1024E_USER_NOTICE kullanıcının yarattığı bildiri mesajısadece PHP 4
 E_ALLdesteklendikleri sürece, yukarıdakilerin hepsi 

Yukarıdaki değerler (sayısal veya sembolik) hangi hataların bildirileceğini belirleyen bit maskesini oluştururken kullanılır. Bu değerleri birleştirmeyi veya bazılarını maskelemeyi bit-tabanlı işlemler ile yapabilirsiniz. php.ini içinde sadece '|', '~', '!' ve '&' işlemlerinin anlaşılacağına, ve php3.ini içinde hiçbirinin anlaşılmayacağına dikkat edin.

PHP 4'te öntanımlı error_reporting değeri E_ALL & ~E_NOTICE'dir ve anlamı E-NOTICE-seviyesi dışındaki tüm hataların ve uyarıların bildirilmesidir. PHP 3'de öntanımlı ayar (E_ERROR | E_WARNING | E_PARSE)'dır ve anlamı öncekiyle aynıdır. Fakat dikkat edin ki, PHP 3'ün php3.ini dosyasında sabitler desteklenmediğinden error_reporting ayarı sayısal olmak durumundadır; az önce belirtilen değer de 7'ye denk gelir.

Başlangıç değeri ini dosyasında error_reporting direktifiyle, Apache'nizin httpd.conf dosyasında php_error_reporting (PHP 3 için php3_error_reporting) direktifiyle, ve son olarak çalışma esnasında betik içinden error_reporting() fonksiyonuyla belirlenebilir.

Uyarý

Sunucularınızı veya kodlarınızı PHP 3'ten PHP 4'e güncellerken bu ayarları ve error_reporting() fonksiyonu çağrımlarını kontrol etmelisiniz, yoksa istemeyerek yeni hata çeşitlerinin bildirimlerini kapatabilirsiniz, özellikle E_COMPILE_ERROR'u. Bu, hatanın ne ve nerede olduğuna dair hiç bir bilgi bırakmadan betiklerinizin tamamiyle boş sayfalar üretmesine yolaçabilir.

Tüm PHP ifadeleri @ ön-ekiyle çağrılabilir. Bu ön-ek, o ifade için hata bildirimini kapatacaktır. Eğer böyle bir ifade sırasında hata oluşursa, ve track_errors özelliği aktifse, hata mesajını $php_errormsg genel değişkeninde bulabilirsiniz.

Not: @ hata-kontrol işlemi ön-eki, ayrıştırma hatalarını kapatmayacaktır.

Uyarý

Şu an için @ hata-kontrol işlemi ön-eki betik sonlandırılmasına yol açacak kritik hataların bile gösterilmesini engelleyecektir. Diğer şeylerin dışında, bu demektir ki @ ön-ekini belli fonksiyonlardan gelecek hataları bastırmak için kullanırsanız, ve bu fonksiyonlar tanımlı değilse, betik nedeni belirtilmeden sonlandırılacaktır.

Aşağıda PHP'deki hata kontrolü işlemlerinin kullanımına ilişkin bir örnek bulacaksınız. Burada bilgileri XML formatında bir günlükte saklayan ve programcıya kritik hatalarda e-mail yollayan bir hata işleme fonksiyonu tanımlıyoruz.

Örnek 15-1. Betik için hata işlemenin kullanımı

<?php
// kendi bildirimimizi kendimiz yapacağız
error_reporting(0);

// kullanıcı tarafından belirlenen hata işleme fonksiyonu
function userErrorHandler ($errno, $errmsg, $filename, $linenum, $vars) {
    // girilen hata için zaman değeri
    $dt = date("Y-m-d H:i:s (T)");

    // hata dizgileri için bir ilişkili dizi tanımla
    // gerçekte ilgilenmemiz gereken değerler sadece
    // 2, 8, 256, 512, ve 1024
    $errortype = array (
                1   =>  "Hata",
                2   =>  "Uyarı",
                4   =>  "Ayrıştırma Hatası",
                8   =>  "Bildirim",
                16  =>  "Çekirdek Hatası",
                32  =>  "Çekirdek Uyarısı",
                64  =>  "Derleme Hatası",
                128 =>  "Derleme Uyarısı",
                256 =>  "Kullanıcı Hatası",
                512 =>  "Kullanıcı Uyarısı",
                1024=>  "Kullanıcı Bildirimi"
                );
    // değişken izi kaydedilecek hatalar
    $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."</errnumber>\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";
    
    // deneme için
    // echo $err;

    // hata günlüğünü kaydet, ve kritik kullanıcı hatalarında bana mail yolla
    error_log($err, 3, "/usr/local/php4/error.log");
    if ($errno == E_USER_ERROR)
        mail("phpdev@mydomain.com","Kritik Kullanıcı Hatası",$err);
}


function distance ($vect1, $vect2) {
    if (!is_array($vect1) || !is_array($vect2)) {
        trigger_error("Bozuk parametreler, dizi bekleniyordu", E_USER_ERROR);
        return NULL;
    }

    if (count($vect1) != count($vect2)) {
        trigger_error("Vektörlerin aynı boyutta olması gerekiyor", 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("Vektör 1'in $i koordinatı sayı değil, 0 olarak alındı", 
                            E_USER_WARNING);
            $c1 = 0.0;
        }
        if (!is_numeric($c2)) {
            trigger_error("Vektör 2'in $i koordinatı sayı değil, 0 olarak alındı", 
                            E_USER_WARNING);
            $c2 = 0.0;
        }
        $d += $c2*$c2 - $c1*$c1;
    }
    return sqrt($d);
}

$old_error_handler = set_error_handler("userErrorHandler");

// tanımlanmamış sabit, uyarı oluşturur
$t = I_AM_NOT_DEFINED;

// bazı "vektörler" tanımla
$a = array(2,3,"foo");
$b = array(5.5, 4.3, -1.6);
$c = array (1,-3);

// kullanıcı hatası oluşturur
$t1 = distance($c,$b)."\n";

// başka bir kullanıcı hatası oluşturur
$t2 = distance($b,"i am not an array")."\n";

// uyarı oluşturur
$t3 = distance($a,$b)."\n";

?>
Bu Hata İşleme ve Günlük fonksiyonları hakkında basit bir örnek.

Ayrıca bkz. error_reporting(), error_log(), set_error_handler(), restore_error_handler(), trigger_error(), user_error()