Hata Ayıklama
Hata çeşitleri ve nasıl ayıklanabilecekleri Kod çalışırken oluşan hatalar Bu tip hatalar kod yazım hatası değildir sadece kodun çalışma esnasında oluşurlar. İyi yazılan bir kod bu tür hataları yakalayabilmelidir. → kullanıcı(muhtemelen programcı) problemden kesinlikle haberdar olmalıdır.
Hata düzeyini anlama Eğer kodun düzgün çalışmasını engelleyen bir problem varsa, → PHP bir hata tetikler. 15 değişik hata seviyesi(türü) vardır. Her biri bir tam sayı ile ilişkilendirilmiş bir sabittir(constant). Sadece vahim hataların(fatal errors) oluşması durumunda kodunuzun çalışması engellenir.
Hata Düzeyleri Değer Sabit Açıklama 1 E_ERROR (integer) Ölümcül çalışma anı hataları. Bellek ayırma sorunu gibi giderilemeyen hatalar bu sınıfa girer. Böyle hatalar betiğin çalışmasının durmasına sebep olur. 2 E_WARNING (integer) Çalışma anı uyarıları (ölümcül olmayan hatalar). Betiğin çalışması durmaz. 4 E_PARSE (integer) Derleme anı çözümleme hataları. Çözümleme hatalarını sadece çözümleyici üretir. 8 E_NOTICE (integer) Çalışma anı bildirimleri. Betikte bir hataya sebep olabilecek fakat betiğin normal çalışmasını esnasında oluşmayabilecek bir şeylerin saptandığını belirtir. 16 E_CORE_ERROR (integer) PHP'nin başlatılması sırasında oluşan ölümcül hatalar. PHP çekirdeği tarafından üretilmesi dışında E_ERROR gibidir. 32 E_CORE_WARNING (integer) PHP'nin başlatılması sırasında oluşan uyarılar (ölümcül olmayan hatalar). PHP çekirdeği tarafından üretilmesi dışında E_WARNING gibidir. 64 E_COMPILE_ERROR (integer) Ölümcül derleme anı hataları. Zend betik motoru tarafından üretilmesi dışında E_ERROR gibidir. 128 E_COMPILE_WARNING (integer) Derleme anı uyarıları (ölümcül olmayan hatalar). Zend betik motoru tarafından üretilmesi dışında E_WARNING gibidir. 256 E_USER_ERROR (integer) Kullanıcı üretimi hata iletileri. PHP işlevi trigger_error() tarafından PHP kodunda üretilmesi dışında E_ERROR gibidir. 512 E_USER_WARNING (integer) Kullanıcı üretimi uyarı iletileri. PHP işlevi trigger_error() tarafından PHP kodunda üretilmesi dışında E_WARNING gibidir. 1024 E_USER_NOTICE (integer) Kullanıcı üretimi bildirim iletileri. PHP işlevi trigger_error() tarafından PHP kodunda üretilmesi dışında E_NOTICE gibidir. 2048 E_STRICT (integer) Yazdığınızı PHP kodunun ileriye dönük uyumluluğunu ve birlikte çalışabilirliğini en iyilemek amacıyla PHP tarafından yapılan önerileri etkin kılar. 4096 E_RECOVERABLE_ERROR (integer) Yakalanabilir ölümcül hata. Tehlikeli olma olasılığı bulunan bir hata oluştuğunu fakat yorumlayıcıyı kararsız durumda bırakmadığını belirtir. Hata, kullanıcı tarafından bir eylemci tanımlanarak yakalanmadığı ( set_error_handler() işlevine bakınız) takdirde betik E_ERROR hatasıyla sonlanır. 8192 E_DEPRECATED (integer) Çalışma anı bildirimleri. Gelecek sürümlerle çalışmayacak kodlar hakkındaki uyarıları etkin kılar. 16384 E_USER_DEPRECATED (integer) Kullanıcı üretimi kullanımı önerilmiyor bildirimleri. PHP işlevi trigger_error() tarafından PHP kodunda üretilmesi dışında E_DEPRECATED gibidir. 30719 E_ALL (integer) Desteklenen (PHP 6'da E_STRICT dışında kalan) tüm hatalar ve uyarılar.
Hata atma (oluşturma) PHP bir problemle karşılaştığında hemen hata oluştu atımını yapar. Siz de hata atımı yapabilirsiniz. Amacı → kullanıcının anlayabileceği hata mesajları oluşturmak. trigger_error() → E_USER_NOTICE hatasını atar bu E_NOTICE ile eşdeğerdir. İkinci argümanı kullanarak E_USER_WARNING hatası oluşturulabilir. E_USER_ERROR hatası (bir vahim hatadır(fatal error) — bu hatayı oluşturmak kodun çalışmasını durdurur): trigger_error( “Houston,sorunumuz var.”, E_USER_WARNING ); trigger_error( “Houston, çok önemli bir sorunumuz var.”, E_USER_ERROR );
Örnek <?php function hesapla( $toplam, $gun) { return ( $toplam / $gun ); } echo hesapla ( 10, 0 ); ? > Eğer $gün için sıfır değeri kullanılırsa PHP aşağıdaki hata ile sonuçlanır. PHP Warning: Division by zero in kodcugum.php on line 3 (PHP uyarısı: kodcugum.php nin 3. satırında sıfıra bölme hatası var) Bu kullanıcı açısından açıklayıcı bir mesaj değildir.
Örnek <?php function hesapla( $toplam, $gun ) { if ( $gun == 0 ) { trigger_error( “hesapla(): gün değişkeni sıfır olamaz”, E_USER_WARNING ); return false; } else { return ( $toplam / $gun ); } echo hesapla( 10, 0 ); ?> Bu mesaj şimdi daha açıklayıcı hale gelmiştir : PHP Warning: hesapla(): gün değişkeni sıfır olamaz in kodcugum.php on line 4
Hata mesajlarının nereye gideceğini kontrol etme PHP genelde hatanın bir günlüğünü (logunu) tutar. PHPde bir iki ayar yaparak hataların kaydının nerede tutulacağını kontrol etmek mümkündür. : display_errors : Gezginde gösterilip gösterilmeyeceğini kara verir. Eğer değeri 1 ise gösterilir 0 ise gösterilmez. (php.ini) --> Hata mesajları hackerler için kullanışlı bilkgiler sunabilir. log_errors : Eger bir ise hataların bir dosyada tutulmasını sağlar. 0 ise hatalar hata dosyasına kaydedilmez. error_log : Hata dosyasın adını ve tam adresini tutar. Varsayılan adresi Web sunucularının hata dosyalarıdır. Eğer sunucudaki php.ini dosyasına erişiminiz var ise örneğin: display_errors = 0 veya 1 yapabilirsiniz Sunucudaki php.ini dosyasına ulaşamıyorsanız ini_set() komutunu kullanabilirsiniz. Örneğin: ini_set( “display_errors”, “0” );
Kendi hata mesajlarınızın güncesini(log) tutmak error_log() fonksiyonu hata mesajlarını sistem güncesine yazmamıza veya ayrı bir dosyaya kaydetmemize veya e-mail olarak birilerine atmamıza olanak sağlar. trigger_error() ün aksine error_log() yakalayabileceğimiz hatalar oluşturmayı veya kodun çalışmasını durdurmayı hedeflemez. error_log() u kullanmak için, onu istediğimiz mesajla çalıştırmalıyız: error_log( “Houston, 21 inde sorun mu çıkacak” );
Kendi hata mesajlarınızın güncesini(log) tutmak Hata mesajları PHP tarafından genelde varsayılan olarak atanan sistem güncesine veay web sunucusu güncesine kaydedilir. Eğer farklı bir dosyada tutulmasını istiyorsak ikinci bir argüman yardımı ile bunu yapabiliriz. İkinci argümana değer olarak 1’i atarsak mesajın e-posta yolu ile gönderilmesini sağlar. Bu durmda 3. argüman olarak e-posta adresi belirtilmelidir. 4. argüman isteğe bağlıdır ve ek olarak e-posta başlıkları göndermemizi sağlar : error_log( “Houston, sorun var”, 1, “joe@example.com”, “Cc: bill@ example.com” ); Eğer değer olarak 3’ü gönderirsek farklı bir dosyada hatalar kaydedilir: error_log( “Houston, sorun var\n”, 3, “/home/joe/custom_errors.log” ); error_log() yeni satır eklemez o yüzden ( \n ) mesaj sonunda kullanılmıştır. error_log() mesaj işlemi başarılı olmuşsa true olmamışsa false döndürür.
Hata raporu düzeyleri Genelde, PHP hata ayıklayıcısı () E_NOTICE haricindeki bütün hataları güncelere kaydeder. Bu ayarı değiştirmek mümkündür. error_reporting() fonksiyonuna güncelerde tutulmasını istediğimiz hata raporu düzeyini ileterek ayarı değiştiririz. Örneğin, sadece E_ERROR hatalarının tutulması için(diğer hastalar gözardı edilecek) : error_reporting( E_ERROR ); Birden fazla hata çeşidi için | kullanılabilir: error_reporting( E_ERROR | E_WARNING | E_PARSE ); Bütün hatalar için E_ALL : error_reporting( E_ALL ); Bunlar dışındaki bütün hatalar demek için: error_reporting( E_ALL ^ E_NOTICE ^ E_USER_NOTICE ); Hiçbir hatanın raporlanmaması için: error_reporting( 0 );
Hata atma (İstisnalar) Kodumuzda istediğimiz zaman hata oluşturmak için: throw new Exception; EK olarak hata mesajı da eklenebilir. throw new Exception( “Oops, biryerlerde yanlışlık var” ); Eğer uygulamamızda değişik birçok hata mesajımız var ise hataların nerelerde oluştuğunu anlayabilmek için her mesaja farklı bir kod vermemiz önemlidir. Bunu yapmak için ikinci bir isteğe bağlı argüman kullanabiliriz. throw new Exception( “Oops, biryerlerde yanlışlık var”, 123 );
Hata Atma (istisnalar) Eğer attığımız hatayı yakalamaz isek sayfamızın başında mesaj olarak gösterilir. Örnek: PHP Fatal error: Uncaught exception ‘Exception’ with message ‘Oops, biryerlerde yanlışlık var’ in script.php:4 Stack trace: #0 {main} thrown in script.php on line 4 Bu mesaj bir hata oluştuğunu ve hatanın denetimsiz olduğunu anlatır ve hata mesajını gösterir. Ayrıca kodumuzun geriye kalanı çalıştırılmaz.
Hataları yakalama try ... catch bloğu kullanarak hataları yakalayabiliriz: try { // hata oluşturan kodumuz } catch ( Exception $e ) { // Hata oluştuğunda çalıştırılacak olan kodumuz } // Bir sonraki satır. Try catch arasındaki kod çalıştırılır. Eğer kod sonucu hata oluşmuşsa catch bloğundaki komutlar çalıştırılır. Eğer try catch arasındaki kodumuzda hata yoksa catch bloğundaki kodumuz çalıştırılmaz, bir sonraki satırdan devam edilir. Catch bir parametre bekler (Exception nesnesi) ($e olarak tanımlandı). Oluşan hata sonucu ne yapılacağına programcı karar verir. Metodlarda bir tanesi basitce geriye kalan kodun çalışmasını engellemektir. Örneğin die( “Hata oluştu” );
Hataları yakalama Alternatif olarak, Exception nesnesini oluşan hatayı daha iyi anlamak açısından sorgulayabiliriz. Bütün exception nesneleri aşağıdaki metodları barındırır: getMessage(): Hata mesajını döndürür. getCode(): Hata kodunu döndürür. getFile(): Hatanın oluştuğu dosyanın adını döndürür. getLine(): Hatanın oluştuğu satırı döndürür. getTrace(): Hataya sebep olan satır, fonksiyonlar ve metodlar içerisinde oluşmuşsa bunları sırası ile barındıran bir dizin döndürür. getTraceAsString(): Hataya sebep olan satır, fonksiyonlar ve metodlar içerisinde oluşmuşsa bunları sırası ile barındıran biçimli(formatlı) bir karakterler dizisi(string) döndürür.
Hataları yakalama Örnek olarak, eğer hatamız ciddi bir problem oluşturmuyorsa hata mesajını yazdırı geriye kalan kodun çalışmasını sağlayabiliriz. try { // çalıştırılacak komutlarımız } catch ( Exception $e ) { echo $e- > getMessage(); } // bir sonraki satır Eğer try...catch arasındaki kodumuzda hata oluşmaz ise,PHP catch bloğunu atlar ve bir sonraki satırdan devam eder. (Catch bloğundaki kod çalıştırılmaz)
Trigger_Error ve Throw Trigger_error ve throw birbirinden farklıdır. Trigger_error vahim olmak zorunda değildir. Throw her zaman vahim hatadır ve yaskalanmaz ise sorun oluşturur.