Ö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 genellikle daha spesifik hata türlerine ihtiyaç duyar. Bir özel istisna hiyerarşisi oluşturmak, alanınıza (domain) uygun istisnalar tanımlamanıza ve bunları farklı özgünlük seviyelerinde 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ı nasıl genişlettiğine dikkat edin. Bu, tüm ödeme ile ilgili istisnaları tek bir catch bloğu ile yakalayabileceğiniz veya belirli olanları tek tek ele alabileceğiniz bir hiyerarşi oluşturur.
Özel istisnalar (custom exceptions), 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, kodunuzu daha sürdürülebilir hale getirir. İstisnaları yakalarken, gerektiği kadar genel veya spesifik olabilirsiniz ve istisna nesnelerinin kendileri, neyin yanlış gittiğine dair anlamlı bir bağlam taşır.
Görev
KolayFarklı türdeki sipariş hatalarını işleyen özel bir istisna (exception) hiyerarşisine sahip bir sipariş işleme sistemi oluşturalım. Hata ayıklamayı daha kesin ve bilgilendirici hale getiren, neyin yanlış gittiğine dair anlamlı bağlam taşıyan istisnalar oluşturacaksınız.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
OrderException.php—Exceptionsınıfını genişleten temel birOrderExceptionsınıfı oluşturun. Bu, siparişle ilgili tüm istisnalar için ebeveyn görevi görür ve gerektiğinde tek bir catch bloğu ile herhangi bir sipariş sorununu yakalamanıza olanak tanır.OutOfStockException.php—OrderExceptionsınıfını genişleten birOutOfStockExceptionsınıfı oluşturun. Bu istisna, yapıcı metodunda (constructor) bir ürün adı ve talep edilen miktarı kabul etmelidir. Bu özel (private) özellikler için constructor promotion kullanın. Ebeveyn yapıcıyı"[productName] is out of stock (requested: [quantity])"formatında bir mesajla çağırın. Ürün adını döndüren birgetProductName(): stringmetodu ekleyin.InvalidQuantityException.php—OrderExceptionsınıfını genişleten birInvalidQuantityExceptionsınıfı oluşturun. Bu istisna, constructor promotion kullanarak özel bir özellik olarak bir miktar değerini yapıcı metodunda kabul etmelidir. Ebeveyn yapıcıyı"Invalid quantity: [quantity]"mesajıyla çağırın. Miktar değerini döndüren birgetQuantity(): intmetodu ekleyin.main.php— Her üç istisna dosyasını da dahil edin. İki girdi alacaksınız: bir ürün adı ve bir miktar (tam sayıya dönüştürülmesi gereken bir dize olarak).Miktar değerine bağlı olarak uygun istisnayı fırlatın:
- Eğer miktar 1'den küçükse, bir
InvalidQuantityExceptionfırlatın - Eğer miktar 100'den büyükse, bir
OutOfStockExceptionfırlatın (yetersiz stoğu simüle ederek) - Aksi takdirde,
"Order placed: [quantity]x [productName]"yazdırın
İstisnaları hiyerarşiyi kullanarak yakalayın. Önce
InvalidQuantityExceptionistisnasını yakalayın ve istisnanın mesajını vegetQuantity()metodunu kullanarak"Quantity error: [message] (value: [quantity])"yazdırın. ArdındanOutOfStockExceptionistisnasını yakalayın ve istisnanın mesajını vegetProductName()metodunu kullanarak"Stock error: [message] (product: [productName])"yazdırın.- Eğer miktar 1'den küçükse, bir
Bu hiyerarşi, temel OrderException sınıfı aracılığıyla siparişle ilgili tüm sorunları yakalama seçeneğine sahip olmaya devam ederken, belirli istisnaları ayrı ayrı yönetmenize olanak tanır. Her istisna üzerindeki özel metodlar, genel bir istisnanın sunamayacağı bağlamı sağlar.
Kopya kağıdı
Exception sınıfını veya onun alt sınıflarını genişleterek özel istisnalar (custom exceptions) oluşturun:
<?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;
}
}
Özel istisnalar, diğer özel istisnaları genişleterek bir hiyerarşi oluşturabilir. Bu, istisnaları farklı özgünlük seviyelerinde yakalamanıza olanak tanır; ödeme ile ilgili tüm istisnaları PaymentException ile yakalayabilir veya InsufficientFundsException gibi belirli olanları ayrı ayrı ele alabilirsiniz.
Özel istisnalar, hata hakkında bağlam sağlamak için ek özellikler ve yöntemler içerebilir:
<?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;
}
}
Özellikleri doğrudan yapıcı (constructor) parametrelerinde tanımlamak için "constructor promotion" özelliğini kullanın. İstisna mesajını ayarlamak için parent::__construct() metodunu çağırın.
Kendin dene
<?php
// Tüm istisna 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şlemini yönetmek için try-catch kullanın
// try bloğu içinde:
// - Eğer miktar < 1 ise, InvalidQuantityException fırlatın
// - Eğer miktar > 100 ise, OutOfStockException fırlatın
// - Aksi takdirde, "Order placed: [quantity]x [productName]" yazdırın
//
// Önce InvalidQuantityException'ı yakalayın:
// - getMessage() ve getQuantity() kullanarak "Quantity error: [message] (value: [quantity])" yazdırın
//
// OutOfStockException'ı yakalayın:
// - getMessage() ve getProductName() kullanarak "Stock error: [message] (product: [productName])" yazdırın
?>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
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon11Tip Sistemi ve Hata Yönetimi
Tip BildirimleriNullable TiplerBirleşim ve Kesişim Tipleriİstisna SınıflarıÖzel İstisna HiyerarşisiTry, Catch, FinallyÖzet - Form Doğrulayıcı3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi