Anlamlı bir şey yapmak istemiyorsanız istisnayı yakalamamalısınız .
"Anlamlı bir şey" bunlardan biri olabilir:
İstisnayı işleme
En belirgin anlamlı eylem, istisnayı ele almak, örneğin bir hata mesajı görüntüleyerek ve işlemi iptal ederek:
try {
$connect = new CONNECT($db, $user, $password, $driver, $host);
}
catch (Exception $e) {
echo "Error while connecting to database!";
die;
}
Günlük tutma veya kısmi temizleme
Bazen bir istisnayı belirli bir bağlam içinde nasıl düzgün bir şekilde ele alacağınızı bilmiyorsunuz; "büyük resim" hakkında bilgi sahibi olmayabilirsiniz, ancak hatayı olabildiğince yakın bir yere kaydetmek istersiniz. Bu durumda, yakalamak, günlüğe kaydetmek ve yeniden atmak isteyebilirsiniz:
try {
$connect = new CONNECT($db, $user, $password, $driver, $host);
}
catch (Exception $e) {
logException($e); // does something
throw $e;
}
İlgili bir senaryo, başarısız işlem için bir miktar temizleme gerçekleştirmek için doğru yerde olduğunuz, ancak hatanın en üst düzeyde nasıl ele alınması gerektiğine karar vermediğiniz yerdir. Önceki PHP sürümlerinde bu,
$connect = new CONNECT($db, $user, $password, $driver, $host);
try {
$connect->insertSomeRecord();
}
catch (Exception $e) {
$connect->disconnect(); // we don't want to keep the connection open anymore
throw $e; // but we also don't know how to respond to the failure
}
PHP 5.5 finally
anahtar kelimeyi tanıttı , bu yüzden temizleme senaryoları için şimdi buna yaklaşmanın başka bir yolu var. Ne olursa olsun temizleme kodunun çalışması gerekiyorsa (yani hem hatada hem de başarıda), artık atılan istisnaların yayılmasına izin verirken bunu yapmak mümkündür:
$connect = new CONNECT($db, $user, $password, $driver, $host);
try {
$connect->insertSomeRecord();
}
finally {
$connect->disconnect(); // no matter what
}
Hata soyutlama (istisna zincirleme ile)
Üçüncü durum, olası birçok başarısızlığı mantıksal olarak daha büyük bir şemsiye altında gruplamak istediğiniz yerdir. Mantıksal gruplama için bir örnek:
class ComponentInitException extends Exception {
// public constructors etc as in Exception
}
class Component {
public function __construct() {
try {
$connect = new CONNECT($db, $user, $password, $driver, $host);
}
catch (Exception $e) {
throw new ComponentInitException($e->getMessage(), $e->getCode(), $e);
}
}
}
Bu durumda, kullanıcıların Component
bir veritabanı bağlantısı kullanılarak uygulandığını bilmelerini istemezsiniz (belki de seçeneklerinizi açık tutmak ve gelecekte dosya tabanlı depolama kullanmak istersiniz). Yani sizin şartnameniz Component
"başlatma hatası ComponentInitException
durumunda atılacak" derdi . Bu, tüketicilerin Component
beklenen türden istisnaları yakalamasına ve hata ayıklama kodunun tüm (uygulamaya bağlı) ayrıntılara erişmesine izin verir .
Daha zengin bağlam sağlama (istisna zincirleme hariç)
Son olarak, istisna için daha fazla bağlam sağlamak isteyebileceğiniz durumlar vardır. Bu durumda, istisnayı, hata oluştuğunda ne yapmaya çalıştığınız hakkında daha fazla bilgi tutan başka bir duruma kaydırmak mantıklıdır. Örneğin:
class FileOperation {
public static function copyFiles() {
try {
$copier = new FileCopier(); // the constructor may throw
// this may throw if the files do no not exist
$copier->ensureSourceFilesExist();
// this may throw if the directory cannot be created
$copier->createTargetDirectory();
// this may throw if copying a file fails
$copier->performCopy();
}
catch (Exception $e) {
throw new Exception("Could not perform copy operation.", 0, $e);
}
}
}
Bu durum yukarıdakine benzerdir (ve örnek muhtemelen ortaya çıkabilecek en iyi örnek değildir), ancak daha fazla bağlam sağlama noktasını gösterir: bir istisna atılırsa, dosya kopyasının başarısız olduğunu bildirir. Ama neden başarısız oldu? Bu bilgiler, istisnalar dışında sağlanmıştır (örnek çok daha karmaşıksa birden fazla seviye olabilir).
Örneğin, bir UserProfile
nesne oluşturmanın dosyaların kopyalanmasına neden olduğu ve kullanıcı profili dosyalarda saklandığından ve işlem semantiğini desteklediği bir senaryo düşünürseniz, bunu yapmanın değeri gösterilir : değişiklikleri yalnızca bir tamamlanana kadar profilin kopyası.
Bu durumda,
try {
$profile = UserProfile::getInstance();
}
ve sonuç olarak "Hedef dizin oluşturulamadı" istisna hatası yakalandığında, karıştırılma hakkınız olur. Bağlam sağlayan diğer istisnaların katmanlarındaki bu "çekirdek" istisnayı silmek hatayı ele almayı çok daha kolaylaştıracaktır ("Profil kopyası oluşturma başarısız oldu" -> "Dosya kopyalama işlemi başarısız oldu" -> "Hedef dizin oluşturulamadı").