PHP kodlarınızdaki hataları görünür kılmak için betiğinizin başlangıcına
ini_set('display_errors', '1'); ve error_reporting(E_ALL); satırlarını ekleyebilirsiniz. İlk komut, PHP'nin hata mesajlarını ekrana yazdırmasını sağlarken; ikincisi, uyarılar ve kullanım dışı (deprecated) bildirimleri de kapsayacak şekilde tüm hataların raporlanmasını sağlar.
PHP:
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
Bu ayarlar etkinleştirildiğinde, örneğin henüz tanımlanmamış bir değişkeni okumaya çalışmak gibi hatalar sessizce geçiştirilmez; bunun yerine hangi dosyada ve hangi satırda sorun olduğu belirtilerek bir hata mesajı ekrana basılır:
Kod:
Warning: Undefined variable $total in /home/index.php on line 7
error_reporting() fonksiyonu herhangi bir parametre olmadan çağrıldığında, mevcut raporlama ayarını sayısal bir değer olarak döndürür. Belirli bir seviye tanımlayıp bunu tekrar anlamlı isimlere dönüştürdüğünüzde, kodu çalıştırdığınızda sonucu görebilirsiniz:
PHP:
<?php
error_reporting(E_ALL & ~E_DEPRECATED);
$level = error_reporting();
echo "Current level: $level (E_ALL is " . E_ALL . ")\n";
foreach (get_defined_constants(true)['Core'] as $name => $value) {
if (str_starts_with($name, 'E_') && $name !== 'E_ALL') {
echo str_pad($name, 20), ($level & $value) ? "reported" : "off", "\n";
}
}
Hata türleri bit tabanlı tanımlandığı için
E_ALL & ~E_DEPRECATED ifadesi "kullanımdan kaldırılan bildirimler hariç her şeyi raporla" anlamına gelir. İlk satırı error_reporting(E_ERROR | E_WARNING); şeklinde değiştirip kodu çalıştırdığınızda raporlama düzeyinin değiştiğini göreceksiniz.Hataları php.ini Dosyası ile Yönetmek
Kod içerisine yazılan ayarlar yalnızca ilgili betik çalışmaya başladığında devreye girer. Ancak ayrıştırma (parse) hataları da dahil olmak üzere tüm süreçlerde hataları görmek istiyorsanız,
php.ini dosyasında değişiklik yapmalısınız (php --ini komutuyla dosya konumunu bulabilirsiniz):
INI:
; Development
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
Dosyayı düzenledikten sonra Apache veya PHP-FPM servisini yeniden başlatmanız gerekir. Buna karşın,
php -S ile kullanılan yerleşik sunucu ve komut satırı, dosyayı her başlangıçta yeniden okur. php.ini dosyasına erişimin olmadığı paylaşımlı hostinglerde, mod_php ile çalışan Apache sunucuları için .htaccess dosyasına şu satırlar eklenebilir:
Kod:
php_flag display_errors on
php_value error_reporting -1
Buradaki
-1 değeri tüm bitleri aktif ederek E_ALL ile aynı sonucu verir.Hata Seviyeleri Hakkında
| Sabit | Neyle tetiklenir | Betiği durdurur |
|---|---|---|
E_ERROR | Belleğin tükenmesi gibi ölümcül bir çalışma zamanı hatası | evet |
E_PARSE | Dosyadaki sözdizimi hatası | evet |
E_WARNING | Tanımsız değişken veya dizi anahtarı, include içinde eksik dosya | hayır |
E_NOTICE | Küçük sorunlar (PHP 8'de çok azı kaldı) | hayır |
E_DEPRECATED | Gelecekteki bir PHP sürümünün reddedeceği kod | hayır |
E_USER_* | trigger_error() ile kendinizin oluşturduğu hatalar | yalnızca E_USER_ERROR |
E_ALL | Burada listelenmeyen çekirdek ve derleme hataları dahil her seviye |
PHP 8.0 ile birlikte birçok eski uyarı türü istisnaya (exception) dönüştürüldü. Örneğin, sıfıra bölme işlemi
/ veya yerleşik bir fonksiyona yanlış veri türü iletmek, artık PHP 7'den beri tanımsız fonksiyon çağrılarında olduğu gibi bir Error alt sınıfı fırlatır. Bu üç durumu da şu şekilde yakalayabilirsiniz:
PHP:
<?php
$attempts = [
fn() => 10 / 0,
fn() => strlen([]),
fn() => undefinedFunction(),
];
foreach ($attempts as $attempt) {
try {
$attempt();
} catch (Throwable $e) {
echo get_class($e), ": ", $e->getMessage(), "\n";
}
}
İstisnaların yönetimi try ve catch blokları ile yapılır. Uyarılar, bildirimler ve kullanım dışı bildirimleri ise hâlâ burada anlatılan hata raporlama sistemi üzerinden yönetilmektedir.
Hataları Göstermek Yerine Loglamak
Canlıya alınmış bir web sitesinde ziyaretçiler asla hata mesajlarını görmemelidir; çünkü bu mesajlar sunucu yollarını, SQL sorgularını ve kod yapısını açığa çıkararak güvenlik riski oluşturur. Bunun yerine hataları bir log dosyasına yazdırmak en doğru yöntemdir:
INI:
; Production
display_errors = Off
log_errors = On
error_log = /var/log/php/app-errors.log
error_reporting = E_ALL
Canlı ortamlarda
error_reporting = E_ALL ayarını korumaya devam edin. Bu ayarı düşürmek hataları çözmez, sadece sizin onlardan haberdar olmanızı engeller. Kendi özel mesajlarınızı da error_log() fonksiyonunu kullanarak aynı günlüğe iletebilirsiniz:
PHP:
<?php
error_log("Payment failed for order 1042");
Test aşamasında log dosyasını anlık olarak izlemek için
tail -f /var/log/php/app-errors.log komutunu kullanabilirsiniz.set_error_handler ile Uyarıları İstisnalara Dönüştürmek
set_error_handler fonksiyonu, PHP'nin uyarılar, bildirimler ve kullanım dışı bildirimleri karşısındaki standart davranışını kendi yazdığınız bir fonksiyonla değiştirmenize olanak tanır. Yaygın bir yöntem, her bir hatayı ErrorException nesnesine dönüştürmektir; böylece örneğin unutulmuş bir dizi anahtarı hatası, diğer istisnalar gibi kodun akışını durdurur ve yakalanabilir hale gelir:
PHP:
<?php
set_error_handler(function (int $severity, string $message, string $file, int $line): bool {
throw new ErrorException($message, 0, $severity, $file, $line);
});
$prices = ['bread' => 4.5, 'milk' => 1.2];
try {
echo "Bread costs {$prices['bread']}\n";
echo "Cheese costs {$prices['cheese']}\n";
} catch (ErrorException $e) {
echo "Caught: ", $e->getMessage(), " on line ", $e->getLine(), "\n";
}
restore_error_handler();
Hazırlanan işleyici fonksiyon, ilk parametre olarak hata seviyesini aldığı için farklı seviyelere farklı tepkiler verebilir. Aşağıdaki örnekte, sadece kullanım dışı bildirimler loglanırken diğer tüm hatalar istisnaya dönüştürülmektedir:
PHP:
<?php
set_error_handler(function (int $severity, string $message): bool {
if ($severity === E_DEPRECATED || $severity === E_USER_DEPRECATED) {
echo "[log] deprecated: $message\n";
return true; // handled, PHP does nothing more
}
throw new ErrorException($message, 0, $severity);
});
trigger_error("oldFunction() is deprecated, use newFunction()", E_USER_DEPRECATED);
try {
trigger_error("Config value 'timeout' is missing", E_USER_WARNING);
} catch (ErrorException $e) {
echo "Exception: ", $e->getMessage(), "\n";
}
Ölümcül (fatal) ve ayrıştırma (parse) hataları, betiğin çalışmaya devam etmesine izin vermediği için bu işleyiciye ulaşmaz. Bu tür hataları kaydetmek için
error_get_last() değerini okuyan bir kapanış (shutdown) fonksiyonu tanımlamanız gerekir.error_get_last ile Son Hatayı Okumak
Bazı fonksiyonlar, işlem başarısız olduğunda
false döndürür ve nedeni yalnızca bir uyarı olarak bildirir; örneğin mevcut olmayan bir dosya için file_get_contents kullanımı. error_get_last() fonksiyonu bu uyarıyı bir dizi olarak döndürür, bu da kendi özel mesajlarınızı oluşturmak istediğinizde oldukça kullanışlıdır:
PHP:
<?php
$content = @file_get_contents('missing-config.json');
if ($content === false) {
$error = error_get_last();
echo "Could not read the file.\n";
echo "Type: ", $error['type'] === E_WARNING ? 'E_WARNING' : $error['type'], "\n";
echo "Message: ", $error['message'], "\n";
}
Bir ifadenin önündeki
@ operatörü, sadece o işlem için hata mesajlarının bastırılmasını sağlar. Bunu dikkatli kullanmalı ve yalnızca sonucun hemen ardından kontrol yapacağınız durumlarda tercih etmelisiniz; çünkü tek başına kullanılan @ operatörü hataları sadece gizlemiş olur.Sık Yapılan Hata: Hatalar Açık Olmasına Rağmen Sayfanın Boş Kalması
ini_set('display_errors', '1') komutunu eklemenize rağmen hala boş beyaz bir sayfa ile karşılaşıyorsanız, sorun muhtemelen bir ayrıştırma (parse) hatasıdır. PHP, ilk satırı yürütmeden önce dosyanın tamamını ayrıştırır; bu yüzden eksik bir ; veya } karakteri, ini_set çalışmadan önce tüm süreci durdurur. Dosyayı, hata mesajlarını her zaman yazdıran terminal üzerinden kontrol edin:
Bash:
php -l index.php
Kod:
Errors parsing index.php
PHP Parse error: syntax error, unexpected token "," in index.php on line 2
Görünen satır numarası, PHP'nin hata nedeniyle durduğu yeri işaret eder; bu genellikle asıl hatanın bir sonraki satırıdır. Hatayı giderip
No syntax errors detected mesajını görene kadar php -l komutunu tekrar çalıştırın ve ardından sayfayı yenileyin.Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 1
- Görüntüleme
- 11
- Cevaplar
- 4
- Görüntüleme
- 14
- Cevaplar
- 1
- Görüntüleme
- 10
- Cevaplar
- 1
- Görüntüleme
- 11
- Cevaplar
- 5
- Görüntüleme
- 20
