Menu
Coddy logo textTech

Özel İstisna Hiyerarşisi

Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 67 / 91.

PHP'nin yerleşik istisna sınıfları yaygın senaryoları kapsasa da gerçek uygulamalar çoğu zaman daha özel hata türlerine ihtiyaç duyar. Özel bir istisna hiyerarşisi oluşturmak, alanınıza uygun istisnalar tanımlamanıza ve bunları farklı özgüllük düzeylerinde yakalamanıza olanak tanır.

Özel bir istisna oluşturmak için Exception sınıfını veya onun alt sınıflarından birini genişletmeniz yeterlidir:

<?php
class PaymentException extends Exception {}

class InsufficientFundsException extends PaymentException {
    public function __construct(
        private float $required,
        private float $available
    ) {
        parent::__construct("Need $required but only $available available");
    }
    
    public function getShortfall(): float {
        return $this->required - $this->available;
    }
}

InsufficientFundsException sınıfının doğrudan Exception sınıfını değil, PaymentException sınıfını genişlettiğine dikkat edin. Bu, tüm ödemeyle ilgili istisnaları tek bir catch bloğuyla yakalayabileceğiniz veya belirli istisnaları ayrı ayrı ele alabileceğiniz bir hiyerarşi oluşturur.

Özel istisneler, hatayla ilgili ek özellikler ve yöntemler içerebilir. Burada getShortfall(), genel bir istisnanın sunamayacağı yararlı bilgiler sağlar:

<?php
class Wallet {
    public function __construct(private float $balance) {}
    
    public function pay(float $amount): void {
        if ($amount > $this->balance) {
            throw new InsufficientFundsException($amount, $this->balance);
        }
        $this->balance -= $amount;
    }
}

İyi tasarlanmış bir istisna hiyerarşisi, kodunuzun bakımını daha kolay hale getirir. İstisnaları yakalarken gerektiği kadar genel veya özel olabilirsiniz ve istisna nesnelerinin kendileri, neyin yanlış gittiği hakkında anlamlı bağlam taşır.

challenge icon

Görev

Kolay

Farklı türlerdeki sipariş hatalarını işleyen özel bir istisna hiyerarşisine sahip bir sipariş işleme sistemi oluşturalım. Neyin yanlış gittiği hakkında anlamlı bağlam taşıyan istisnalar oluşturacak ve böylece hata işlemeyi daha kesin ve bilgilendirici hâle getireceksin.

Kodunu dört dosyaya ayıracaksın:

  • OrderException.php: Exception sınıfını genişleten temel bir OrderException sınıfı oluştur. Bu sınıf, siparişle ilgili tüm istisnaların üst sınıfı olarak görev yapar ve gerektiğinde tek bir catch bloğuyla herhangi bir sipariş sorununu yakalamanı sağlar.
  • OutOfStockException.php: OrderException sınıfını genişleten bir OutOfStockException sınıfı oluştur. Bu istisna, yapıcısında bir ürün adını ve istenen miktarı kabul etmelidir. Bu özel özellikler için yapıcı destekli özellik tanımlamayı kullan. Üst sınıfın yapıcısını "[productName] is out of stock (requested: [quantity])" biçimindeki bir iletiyle çağır. Ürün adını döndüren getProductName(): string metodunu ekle.
  • InvalidQuantityException.php: OrderException sınıfını genişleten bir InvalidQuantityException sınıfı oluştur. Bu istisna, yapıcısında yapıcı destekli özel bir özellik olarak bir miktar değerini kabul etmelidir. Üst sınıfın yapıcısını "Invalid quantity: [quantity]" iletisiyle çağır. Miktar değerini döndüren getQuantity(): int metodunu ekle.
  • main.php: Her üç istisna dosyasını da dahil et. İki girdi alacaksın: bir ürün adı ve tamsayıya dönüştürülmesi gereken bir dize olarak miktar.

    Miktar değerine göre uygun istisnayı fırlat:

    • Miktar 1'den küçükse bir InvalidQuantityException fırlat
    • Miktar 100'den büyükse bir OutOfStockException fırlat (yetersiz stok durumunu simüle eder)
    • Aksi takdirde "Order placed: [quantity]x [productName]" çıktısını yazdır

    İstisnaları hiyerarşiyi kullanarak yakala. Önce InvalidQuantityException istisnasını yakala ve istisnanın iletisini ve getQuantity() metodunu kullanarak "Quantity error: [message] (value: [quantity])" çıktısını yazdır. Ardından OutOfStockException istisnasını yakala ve istisnanın iletisini ve getProductName() metodunu kullanarak "Stock error: [message] (product: [productName])" çıktısını yazdır.

Bu hiyerarşi, belirli istisnaları ayrı ayrı işlemeni sağlarken aynı zamanda temel OrderException sınıfı aracılığıyla siparişle ilgili tüm sorunları yakalama seçeneğini de sunar. Her istisnadaki özel metotlar, genel bir istisnanın sağlayamayacağı bağlamı sunar.

Kendin dene

<?php
// Tüm exception dosyalarını dahil et
require_once 'OrderException.php';
require_once 'OutOfStockException.php';
require_once 'InvalidQuantityException.php';

// Girdiyi oku
$productName = trim(fgets(STDIN));
$quantity = intval(trim(fgets(STDIN)));

// TODO: Sipariş işlemeyi yönetmek için try-catch kullan
// try bloğu içinde:
//   - Eğer quantity < 1 ise, InvalidQuantityException fırlat
//   - Eğer quantity > 100 ise, OutOfStockException fırlat
//   - Aksi halde, "Order placed: [quantity]x [productName]" yazdır
//
// Önce InvalidQuantityException'ı yakala:
//   - getMessage() ve getQuantity() kullanarak "Quantity error: [message] (value: [quantity])" yazdır
//
// OutOfStockException'ı yakala:
//   - getMessage() ve getProductName() kullanarak "Stock error: [message] (product: [productName])" yazdır

?>
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online PHP derleyicisi