PHP Hata Yönetimi (try-catch)
PHP'de hataları try-catch bloklarıyla yakalamayı öğrenin.
PHP hata yönetimi, bir PHP uygulamasında meydana gelen hataları (uyarılar, bildirimler, fataller vb.) yakalama, işleme, kaydetme ve kullanıcıya uygun bir şekilde sunma sürecini ifade eder. Doğru hata yönetimi, uygulamanın kararlılığını artırır, güvenlik açıklarını azaltır ve hata ayıklama (debugging) sürecini kolaylaştırır.
İşte PHP hata yönetiminin temel bileşenleri ve yöntemleri:
---
### 1. PHP'nin Hata Türleri
PHP'de farklı hata seviyeleri bulunur:
* **E_PARSE (Ayrıştırma Hatası):** Kodun PHP ayrıştırıcısı tarafından okunurken oluşan hatalar. Genellikle sözdizimi hatalarından kaynaklanır ve uygulamanın çalışmasını tamamen durdurur. `set_error_handler` ile yakalanamaz.
* **E_ERROR (Çalışma Zamanı Hatası / Fatal Error):** Uygulamanın çalışmasını durduran kritik hatalar. Örneğin, olmayan bir sınıfın örneğini oluşturmaya çalışmak. `set_error_handler` ile yakalanamaz, ancak `register_shutdown_function` ile yakalanabilir.
* **E_WARNING (Uyarı):** Kritik olmayan hatalardır. Uygulamanın çalışmasını durdurmaz ancak potansiyel bir sorun veya yanlış bir durum olduğunu belirtir. Örneğin, olmayan bir dosyayı `include` etmeye çalışmak. `set_error_handler` ile yakalanabilir.
* **E_NOTICE (Bildirim):** Önemsiz, çalışma zamanı bildirimleridir. Koddaki potansiyel hataları veya kötü uygulamaları belirtir. Örneğin, tanımlanmamış bir değişken kullanmak. `set_error_handler` ile yakalanabilir.
* **E_DEPRECATED (Kullanımdan Kaldırılmış):** Gelecek sürümlerde kaldırılacak olan fonksiyonların veya özelliklerin kullanıldığını belirtir. `set_error_handler` ile yakalanabilir.
* **E_RECOVERABLE_ERROR (Kurtarılabilir Hata):** `E_ERROR` gibi kritik ancak `try-catch` blokları içinde yakalanabilen hatalar. Örneğin, bir tür ipucu (type hint) ihlali. `set_error_handler` ile yakalanabilir.
* **E_STRICT (Katı Mod):** PHP'nin gelecekteki sürümlerle uyumluluğu sağlamak için tavsiye ettiği kodlama standartlarına uyulmadığında üretilen bildirimler. `set_error_handler` ile yakalanabilir.
* **E_ALL:** Tüm hataları, uyarıları ve bildirimleri içerir (bazı `E_STRICT` seviyeleri hariç).
---
### 2. PHP'nin Varsayılan Hata Davranışı (php.ini)
PHP'nin hata yönetimi büyük ölçüde `php.ini` dosyasındaki ayarlarla kontrol edilir.
* **`error_reporting`:** Hangi hata seviyelerinin raporlanacağını belirler.
* Geliştirme Ortamı: `E_ALL` (Tüm hataları görmek için)
* Üretim Ortamı: `E_ALL & ~E_NOTICE & ~E_DEPRECATED` (Sadece kritik hataları görmek ve loglamak için) veya `0` (Hiçbir şeyi raporlamamak için, önerilmez).
* **`display_errors`:** Hataların tarayıcıda doğrudan gösterilip gösterilmeyeceğini belirler.
* Geliştirme Ortamı: `On` (Hata ayıklama için)
* Üretim Ortamı: `Off` (**KESİNLİKLE** `Off` olmalı! Güvenlik ve kullanıcı deneyimi için çok önemlidir.)
* **`log_errors`:** Hataların bir log dosyasına yazılıp yazılmayacağını belirler.
* Geliştirme ve Üretim Ortamı: `On` (Hataları izlemek için gereklidir.)
* **`error_log`:** Hataların yazılacağı dosyanın yolunu belirler. Bu ayar `log_errors = On` olduğunda kullanılır.
**Örnek `php.ini` ayarları:**
```ini
; Geliştirme Ortamı
error_reporting = E_ALL
display_errors = On
log_errors = Off ; veya development.log gibi bir dosyaya yönlendirilebilir.
; Üretim Ortamı
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED
display_errors = Off
log_errors = On
error_log = /var/log/php/errors.log
```
---
### 3. Hata Yönetimi Yöntemleri
#### a) `set_error_handler()`: Özel Hata İşleyici
Bu fonksiyon, PHP'nin varsayılan hata işleyicisinin yerine kendi özel hata işleyicinizi kaydetmenizi sağlar. `E_PARSE` ve `E_ERROR` türündeki hatalar dışındaki tüm hata türlerini yakalayabilir.
```php
function customErrorHandler($errno, $errstr, $errfile, $errline) {
// Hata seviyesine göre işlem yap
switch ($errno) {
case E_USER_ERROR:
echo "<b>Özel HATA:</b> [$errno] $errstr<br>";
echo "Dosya: $errfile, Satır: $errline<br>";
// Kritik hataları logla ve uygulamayı durdur
error_log("Kritik HATA: [$errno] $errstr - $errfile:$errline");
exit(1);
break;
case E_USER_WARNING:
echo "<b>Özel UYARI:</b> [$errno] $errstr<br>";
error_log("UYARI: [$errno] $errstr - $errfile:$errline");
break;
case E_USER_NOTICE:
echo "<b>Özel BİLDİRİM:</b> [$errno] $errstr<br>";
error_log("BİLDİRİM: [$errno] $errstr - $errfile:$errline");
break;
default:
echo "<b>Bilinmeyen hata türü:</b> [$errno] $errstr<br>";
error_log("Bilinmeyen Hata Türü: [$errno] $errstr - $errfile:$errline");
break;
}
// PHP'nin varsayılan hata işleyicisinin çalışmasını engellemek için true döndür
return true;
}
// Özel hata işleyicisini kaydet
set_error_handler("customErrorHandler");
// Test hataları oluştur
trigger_error("Bu bir özel bildirim hatasıdır.", E_USER_NOTICE);
trigger_error("Bu bir özel uyarı hatasıdır.", E_USER_WARNING);
trigger_error("Bu bir özel kritik hata, uygulama durdurulacak.", E_USER_ERROR);
echo "Bu satır, kritik hatadan sonra asla çalışmayacak.";
```
**Dikkat:** `set_error_handler` içinden `die()` veya `exit()` çağrısı yapmadığınız sürece uygulama çalışmaya devam eder. `true` döndürmek, PHP'nin kendi hata işleyicisini çalıştırmasını engeller.
#### b) Exceptions (İstisnalar): `try-catch-finally`
Exceptions, beklenmedik veya hata durumlarını daha yapısal bir şekilde ele almak için modern bir yaklaşımdır. Özellikle öngörülebilir hata durumlarında (örneğin, dosya bulunamadı, geçersiz kullanıcı girişi) tercih edilir.
```php
function bolmeIslemi($bolunen, $bolen) {
if ($bolen === 0) {
throw new Exception("Bölme işlemi sıfıra bölünemez.");
}
return $bolunen / $bolen;
}
try {
echo bolmeIslemi(10, 2) . "<br>"; // 5
echo bolmeIslemi(10, 0) . "<br>"; // Exception fırlatılacak
echo "Bu satır çalışmayacak.<br>";
} catch (Exception $e) {
echo "Hata Yakalandı: " . $e->getMessage() . "<br>";
// Hata mesajını logla
error_log("Bölme Hatası: " . $e->getMessage() . " - Dosya: " . $e->getFile() . " Satır: " . $e->getLine());
} finally {
echo "Her zaman çalışan blok.<br>";
}
// Birden fazla catch bloğu ile farklı exception türlerini yakalayabiliriz
class CustomException extends Exception {}
try {
if (rand(0, 1)) {
throw new Exception("Genel bir hata!");
} else {
throw new CustomException("Özel bir hata!");
}
} catch (CustomException $e) {
echo "Özel hata yakalandı: " . $e->getMessage() . "<br>";
} catch (Exception $e) {
echo "Genel hata yakalandı: " . $e->getMessage() . "<br>";
}
```
**`set_exception_handler()`:** Yakalanmayan (uncaught) istisnalar için genel bir işleyici atamak için kullanılır. Eğer bir istisna `try-catch` bloğu ile yakalanmazsa, bu işleyici devreye girer.
```php
function customExceptionHandler($exception) {
echo "<b>Yakalanmayan İstisna:</b> " . $exception->getMessage() . "<br>";
error_log("Yakalanmayan İstisna: " . $exception->getMessage() . " - Dosya: " . $exception->getFile() . " Satır: " . $exception->getLine());
// Üretim ortamında kullanıcıya dostu bir hata sayfası gösterilebilir
// header("Location: /error.php"); exit();
}
set_exception_handler("customExceptionHandler");
// Bu istisna yakalanmayacak ve customExceptionHandler tarafından işlenecek
throw new Exception("Bu yakalanmayan bir istisnadır!");
echo "Bu satır asla çalışmayacak.";
```
#### c) `register_shutdown_function()`: Fatal Hataları Yakalama
`set_error_handler` fonksiyonu `E_ERROR` (Fatal Error) türündeki hataları yakalayamaz çünkü bu hatalar uygulamanın durmasına neden olur. Ancak, `register_shutdown_function()` ile uygulamanın kapatılma anında çalışan bir fonksiyon kaydedebiliriz. Bu fonksiyon içinde `error_get_last()` kullanarak bir fatal hata olup olmadığını kontrol edebiliriz.
```php
function fatalErrorHandler() {
$error = error_get_last();
// Sadece fatal hataları (E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR) kontrol et
if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
ob_clean(); // Eğer çıktı tamponlama kullanıyorsanız, önceki çıktıyı temizle
// Üretim ortamında kullanıcıya dostu bir hata mesajı göster
echo "<h1>Sistem Hatası</h1>";
echo "<p>Beklenmedik bir hata oluştu. Lütfen daha sonra tekrar deneyin.</p>";
// Loglama
error_log("Fatal Hata: " . $error['message'] . " - " . $error['file'] . ":" . $error['line']);
}
}
register_shutdown_function('fatalErrorHandler');
// Örnek bir fatal hata oluşturmak için (dikkatli kullanın)
// Bu kod bir parse hatası yaratır ve uygulamayı durdurur
// parse_error_simulasyonu
// $object->method(
// bu_bir_parse_hatasi(); // Syntax error, unexpected 'this_is_a_parse_error' (T_STRING)
// Veya çalışma zamanı fatal hatası (non-existent class)
// $nonExistentObject = new NonExistentClass();
// Tanımsız bir fonksiyon çağırmak da fatal hataya yol açabilir.
nonExistentFunction();
echo "Bu satır, fatal hatadan sonra asla çalışmayacak.";
```
#### d) `@` Hata Kontrol Operatörü (Error Control Operator)
Bir ifadenin önüne `@` koymak, o ifadeden kaynaklanan tüm hata mesajlarını susturur.
```php
$file_content = @file_get_contents("non_existent_file.txt");
if ($file_content === false) {
echo "Dosya bulunamadı veya okunamadı.";
}
```
**UYARI:** Bu operatör **genellikle kötü bir pratik olarak kabul edilir**. Hataları gizler ve sorunların tespiti zorlaşır. Hata kontrolü için daha iyi yöntemler (örneğin, `try-catch` veya `if` kontrolleri) kullanılmalıdır.
#### e) Hata Kaydı (Error Logging)
Hataları loglamak, özellikle üretim ortamında uygulamanızın sağlığını izlemek ve sorunları tespit etmek için hayati öneme sahiptir.
* `php.ini` ayarları (`log_errors = On`, `error_log = ...`) ile PHP tarafından otomatik olarak loglanabilir.
* Manuel olarak `error_log()` fonksiyonu ile de loglama yapılabilir:
```php
error_log("Özel bir hata mesajı loglandı.", 0, "/var/log/my_app_errors.log");
// Veya sadece varsayılan log dosyasına:
error_log("Özel bir hata mesajı loglandı.");
```
---
### 4. En İyi Uygulamalar (Best Practices)
1. **Üretim Ortamında Asla Hataları Görüntülemeyin (`display_errors = Off`)**: Bu hem güvenlik açığı yaratır (yol bilgileri, veritabanı şifreleri açığa çıkabilir) hem de kullanıcılara kötü bir deneyim sunar.
2. **Tüm Hataları Loglayın (`log_errors = On`)**: Uygulamanızın üretimde nasıl çalıştığını anlamak için hataları kaydetmek çok önemlidir.
3. **İstisnaları Kullanın (`try-catch`)**: Beklenen hata durumları için istisnalar, daha okunabilir ve yönetilebilir kod sağlar.
4. **`set_error_handler()` ve `set_exception_handler()` Kullanın**: Bu fonksiyonlar, uygulamanızda yakalanmayan hatalar ve istisnalar için genel bir düşüş noktası (fallback) sağlar.
5. **`register_shutdown_function()` ile Fatal Hataları Yakalayın**: Uygulamanın aniden durmasını önlemek ve fatal hatalar meydana geldiğinde temiz bir kapanış veya loglama sağlamak için gereklidir.
6. **Kullanıcıya Dostu Hata Sayfaları Gösterin**: Üretimde bir hata oluştuğunda, kullanıcıya teknik detaylar yerine "Beklenmedik bir hata oluştu, lütfen daha sonra tekrar deneyin." gibi bir mesaj içeren şık bir hata sayfası sunun.
7. **`@` Operatörünü Kullanmaktan Kaçının**: Hataları gizlemek, sorunları teşhis etmeyi zorlaştırır.
8. **Hata Raporlama Seviyesini Yönetin (`error_reporting`)**: Geliştirmede tüm hataları görün, üretimde sadece kritik olanları loglayın.
9. **Özel Hata Sınıfları Kullanın**: Daha karmaşık uygulamalarda, farklı hata durumları için kendi özel istisna sınıflarınızı oluşturmak (örneğin `DatabaseException`, `ValidationException`) kodunuzu daha modüler ve anlaşılır hale getirir.
---
Özetle, PHP hata yönetimi, `php.ini` ayarlarını doğru yapılandırmak, `set_error_handler`, `set_exception_handler` ve `register_shutdown_function` gibi özel işleyiciler kullanmak ve istisnalar (`try-catch`) ile kodunuzdaki potansiyel sorunları proaktif bir şekilde ele almakla ilgilidir. Bu sayede uygulamanız daha sağlam, güvenli ve bakımı daha kolay hale gelir.
Son Paylaşımlar
-
Python Temelleri Genel Tekrar
14:39:24 - 13/12/2025 -
Python Performans İpuçları
14:38:59 - 13/12/2025 -
Python’da Temiz Kod Yazma
14:38:28 - 13/12/2025 -
Python Mini Proje: Sayı Tahmin Oyunu
14:37:58 - 13/12/2025 -
Python Mini Proje: Hesap Makinesi
14:37:31 - 13/12/2025