PHP hatalarını göstermek için betiğinizin en başına şu satırları koyun: ini_set('display_errors', '1'); ve error_reporting(E_ALL);. İlki PHP'nin hata mesajlarını yazdırmasını, ikincisi uyarılar ve kullanımdan kaldırma bildirimleri dahil her türlü hatayı raporlamasını sağlar.
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
Bunlar yerindeyken, hiç atanmamış bir değişkeni okumak gibi bir hata sessizce başarısız olmak yerine dosya ve satır numarasıyla bir mesaj yazdırır:
Warning: Undefined variable $total in /home/index.php on line 7
Argümansız çağrılan error_reporting() mevcut ayarı bir sayı olarak döndürür. Bir seviye ayarlayıp onu tekrar adlara çevirmek için Run'a basın:
Her hata türü bir bittir; bu yüzden E_ALL & ~E_DEPRECATED "kullanımdan kaldırma bildirimleri hariç her şey" demektir. İlk satırı error_reporting(E_ERROR | E_WARNING); olarak değiştirip tekrar çalıştırın.
php.ini içinde hataları göstermek
Betikteki bir ayar ancak betik çalışmaya başladığında uygulanır. Ayrıştırma hataları dahil her betik için hataları göstermek üzere php.ini dosyasını değiştirin (php --ini ile bulabilirsiniz):
; Development
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
Düzenledikten sonra Apache'yi veya PHP-FPM'i yeniden başlatın. php -S yerleşik sunucusu ve komut satırı dosyayı her başlangıçta okur. php.ini erişimi olmayan paylaşımlı hostinglerde, mod_php ile çalışan Apache .htaccess satırlarını da kabul eder:
php_flag display_errors on
php_value error_reporting -1
-1 her biti ayarlar, bu da E_ALL ile aynıdır.
Hata seviyeleri
| 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 birçok eski uyarıyı istisnaya çevirdi: / ile sıfıra bölmek ve yerleşik bir fonksiyona yanlış tür geçirmek artık bir Error alt sınıfı fırlatıyor; tanımsız bir fonksiyonu çağırmanın PHP 7'den beri yaptığı gibi. Üçünü de yakalayabilirsiniz:
İstisnalar try ve catch sayfasında anlatılıyor. Uyarılar, bildirimler ve kullanımdan kaldırma bildirimleri ise hâlâ burada anlatılan hata raporlama sisteminden geçer.
Hataları göstermek yerine loglamak
Canlı bir sitede ziyaretçiler hata mesajlarını asla görmemelidir: bu mesajlar yolları, SQL'i ve kodu açığa çıkarır. Bunun yerine onları bir log dosyasına yazın:
; Production
display_errors = Off
log_errors = On
error_log = /var/log/php/app-errors.log
error_reporting = E_ALL
Canlı ortamda error_reporting = E_ALL ayarını koruyun. Bunu düşürmek hataları ortadan kaldırmaz, yalnızca onlardan haberdar olmanızı engeller. Kendi mesajlarınız da error_log() ile aynı loga gidebilir:
<?php
error_log("Payment failed for order 1042");
Ardından test ederken dosyayı izleyin: tail -f /var/log/php/app-errors.log.
set_error_handler ile uyarıları istisnalara çevirmek
set_error_handler, PHP'nin uyarıları, bildirimleri ve kullanımdan kaldırma bildirimlerini varsayılan olarak ele alışını kendi fonksiyonunuzla değiştirir. Yaygın bir kalıp her birini bir ErrorException hâline getirir; böylece unutulmuş bir dizi anahtarı kodu diğer istisnalar gibi durdurur ve yakalanabilir:
İşleyici, hata seviyesini ilk argüman olarak alır; bu yüzden seviyelere farklı davranabilir. Bu işleyici yalnızca kullanımdan kaldırma bildirimlerini loglar ve geri kalan her şeyi istisnaya çevirir:
Ölümcül hatalar ve ayrıştırma hataları işleyiciye hiç ulaşmaz, çünkü betik onlardan sonra devam edemez. Bunları kaydetmek için error_get_last() değerini okuyan bir kapanış (shutdown) fonksiyonu kaydedin.
error_get_last ile son hatayı okumak
Bazı fonksiyonlar false döndürür ve nedenini yalnızca bir uyarı olarak bildirir; örneğin eksik bir dosya üzerinde file_get_contents. error_get_last() bu uyarıyı bir dizi olarak döndürür; kendi mesajınızı göstermek istediğinizde işe yarar:
Çağrının önündeki @ operatörü yalnızca o ifade için mesajı bastırır. Onu idareli kullanın ve yalnızca burada olduğu gibi sonucu hemen ardından kontrol ettiğinizde kullanın; tek başına bir @ yalnızca hataları gizler.
Sık yapılan hata: hatalar açık ama sayfa hâlâ boş
ini_set('display_errors', '1') eklediğiniz hâlde beyaz bir sayfa görüyorsanız hata büyük olasılıkla bir ayrıştırma hatasıdır. PHP ilk satırı çalıştırmadan önce dosyanın tamamını ayrıştırır; bu yüzden eksik bir ; veya } her şeyi ini_set çalışmadan durdurur. Dosyayı, mesajı her zaman yazdıran terminalden kontrol edin:
php -l index.php
Errors parsing index.php
PHP Parse error: syntax error, unexpected token "," in index.php on line 2
Satır numarası PHP'nin pes ettiği yeri gösterir; bu çoğu zaman asıl hatadan sonraki satırdır. Hatayı düzeltin, No syntax errors detected diyene kadar php -l komutunu tekrar çalıştırın, ardından sayfayı yeniden yükleyin.
Sıkça Sorulan Sorular
PHP'de tüm hataları nasıl gösteririm?
Betiğin en başına ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); ekleyin ya da php.ini içinde display_errors = On ve error_reporting = E_ALL ayarlayıp web sunucusunu veya PHP-FPM'i yeniden başlatın.
PHP sayfam neden boş beyaz bir ekran gösteriyor?
display_errors kapalıyken ölümcül bir hata betiği durdurdu, bu yüzden hiçbir şey yazdırılmadı. Mesajı ve satır numarasını görmek için hataları açın (ya da hata logunu okuyun, örneğin error_log ayarının gösterdiği dosyada tail -f ile).
ini_set('display_errors', 1) neden ayrıştırma hatamı göstermiyor?
Bir ayrıştırma hatası PHP'yi dosyanın hiçbir satırı çalışmadan durdurur, bu yüzden ini_set çağrısı hiç gerçekleşmez. display_errors değerini php.ini içinde ayarlayın ya da ini_set çağrısını, ardından bozuk dosyayı include eden küçük bir dosyaya koyun.
display_errors canlı ortamda açık olmalı mı?
Hayır. Hata mesajları ziyaretçilere dosya yollarını ve kod ayrıntılarını gösterir. Canlı ortamda display_errors = Off, log_errors = On ve bir error_log yolu kullanın; sorunlar yine de kaydedilsin diye error_reporting = E_ALL ayarını koruyun.
error_reporting(0) ne yapar?
Betiğin geri kalanı için her hata türünün raporlanmasını kapatır; böylece uyarılar ve hatta ölümcül hatalar hiçbir mesaj üretmez. Sorunları düzeltmez, gizler; hataları susturmak yerine loglamayı tercih edin.