İstisnalar
PHP diğer programlama dillerindekine benzer bir istisna modeline
sahiptir. Bir istisna oluşturulabilir (&throw;) ve yakalanabilir (&catch;).
Olası istisnaların yakalanabilmesi için, kod bir &try; bloğu içine
alınabilir. Her &try; bloğuna karşılık en az bir tane &catch; veya
&finally; bloğu olması gerekir.
Bir istisna oluşturulursa ve geçerli işlev bağlamında &catch; bloğu yoksa,
istisna, eşleşen bir &catch; bloğu bulana kadar çağrı yığıtını çağıran
işleve "kabarcıklandırır". Yol boyunca karşılaşılan tüm &finally; blokları
çalıştırılır. Eğer çağrı yığıtı, eşleşen bir &catch; bloğu bulamadan
küresel bağlama kadar boşalırsa ve bir küresel istisna işleyici de
atanmamışsa, ölümcül hata vererek sonlanır.
Oluşturulan nesne ya bir Throwable örneği
olmalıdır. Bunu sağlamayan bir nesne oluşturmaya çalışmak (&throw;)
ölümcül bir PHP hatasına yol açmaz.
PHP 8.0.0 ve sonrasında, &throw; sözcüğü bir ifade olup herhangi bir
ifadenin içinde kullanılabilir. Önceki sürümlerde bir deyimdi ve kendi
satırına sahip olması gerekiyordu.
catch
Bir &catch; bloğu oluşturulan bir istisnaya nasıl yanıt verileceğini
tanımlar. Bir &catch; bloğu işleyebileceği bir veya daha fazla istisna
veya hata türünü ve isteğe bağlı olarak istisnanın atanacağı değişkeni
tanımlar. (PHP 8.0.0 öncesinde değişken gerekliydi.) İlk &catch; bloğu,
nesneyi işleyecek &throw; nesnesinin türüyle eşleşen bir hata veya
istisnayla karşılaştığında bunları engelleyecektir.
Farklı sınıflara ait istisnaları yakalamak için birden fazla &catch; bloğu
kullanılabilir. Normal çalışma sıradaki son &catch; bloğundan sonra devam
eder. Buradaki normal çalışma (&try; bloğu içinde hiçbir istisna
oluşmadığında) sıradaki tanımlanmış son &catch; bloğundan sora devam eder.
İstisnalar bir &catch; bloğu içerisinde oluşmuş olabileceği gibi yeniden
de oluşabilir (&throw;). Aksi takdirde, çalışma, tetiklenen &catch;
bloğundan sonra devam eder.
Bir istisna oluştuğunda, istisnanın oluştuğu yerden sonraki kodlar
çalıştırılmaz ve PHP oluşan istisna ile uyuşan ilk &catch;
bloğunu bulmaya çalışır. Bir istisnanın yakalanmaması durumunda,
set_exception_handler işlevi ile evvelce bir istisna
eylemcisi tanımlanmamışsa, PHP bir ölümcül hata durumu oluşturur ve bir
"Uncaught Exception ..." ("Yakalanmamış istisna ...")
iletisi çıktılar.
PHP 7.1.0 ve sonrasında, boru (|) karakteri kullanarak
bir &catch; bloğunda çok sayıda istisna belirtilebilir. Farklı sınıf
hiyerarşilerindeki farklı istisnalar aynı şekilde elde edildiğinde
kullanışlıdır.
PHP 8.0.0 ve sonrasında, değişken ismi yakalama istisnası için isteğe
bağlıdır. Belirtilmezse, &catch; bloğu çalışmaya yine de devam eder fakat
istisnayı oluşturacak nesneye erişemez.
finally
&catch; bloklarının yerine veya sonrasında bir
&finally; bloğu da belirtilebilir. Bir istisnanın oluşmamışsa bile ve
normal çalışmaya dönülmeden önce &finally; bloğu içindeki kodlar daima
&try; ve &catch; bloklarından sonra çalıştırılır.
Dikkate değer tek etkileşim, &finally; bloğu ile &return; deyimi arasında
olur. &try; veya &catch; bloklarının içinde bir &return; deyimine
rastlansa bile &finally; bloğu çalışmasına devam edeceği gibi, &return;
deyimi de çalıştırılır fakat &finally; bloğu işini bitirdikten sonra sonuç
döndürülür. Ek olarak, &finally; bloğu da bir &return; içeriyorsa
&finally; bloğundaki değer döndürülür.
Küresel istisna işleyici
Eğer bir istisnanın küresel bağlama kadar kabarcıklanmasına izin verilirse,
atandığı takdirde bir küresel istisna işleyici tarafından yakalanabilir.
Başka bir blok çalıştırılmazsa bir &catch; bloğu yerine çağrılmak üzere bir
işlev set_exception_handler işlevi ile atanabilir.
Etkisi esasen, tüm programın, &catch; olarak bu işleve sahip bir &try;-
&catch; bloğu ile sarmalanmasıyla aynıdır.
&reftitle.notes;
Yerleşik PHP işlevleri aslında hata
raporlama yapmakta, istisnaları sadece nesne yönelimli güncel eklentiler
kullanmaktadır. Bununla birlikte hatalar ErrorException ile kolayca
istisnalara dönüştürülebilir. Bununla birlikte, bu teknik sadece ölümcül
hatalarda çalışır.
- Hata raporlamayı istisnalara dönüştürme örneği
]]>
Standard PHP Kütüphanesi (SPL) bol bol
yerleşik istisna içerir.
&reftitle.examples;
- Bir İstisna Oluşturmak
getMessage(), "\n";
}
// Çalışma sürer
echo 'Merhaba Dünya';
?>
]]>
&example.outputs;
- Bir &finally; bloğu ile istisnanın işleme sokulması
getMessage(), "\n";
} finally {
echo "İlk finally bloğu.\n";
}
try {
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'İstisna yakalandı: ', $e->getMessage(), "\n";
} finally {
echo "İkinci finally bloğu.\n";
}
// İcra sürer
echo "Merhaba Dünya\n";
?>
]]>
&example.outputs;
- &finally; bloğu ile &return; arasındaki etkileşim örneği
]]>
&example.outputs;
- İç içe istisnalar
getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>
]]>
&example.outputs;
Çoklu catch istisna eldesi
testing();
?>
]]>
&example.outputs;
- Yakalama değişkeninin olmayışıSadece PHP 8.0.0 ve sonrası için geçerlidir.
]]>
- Bir ifade olarak throwSadece PHP 8.0.0 ve sonrası için geçerlidir.
getMessage();
}
?>
]]>
İstisnaları Genişletmek
Yerleşik Exception sınıfını genişleten kullanıcı
tanımlı bir istisna sınıfı tanımlanabilir. Aşağıdaki üyeler ve
özellikler, yerleşik Exception sınıfından
türetilen alt sınıf içerisinde nelerin erişilebilir olduğunu
göstermektedir.
- Yerleşik Exception sınıfı
]]>
Bir sınıf yerleşik Exception sınıfını genişletiyor
ve nesne kurucuyu yeniden
tanımlıyorsa, mevcut tüm verinin düzgün biçimde atandığından emin olmak
için parent::__construct() işlevinin de çağrılması hararetle önerilir.
Nesne bir karakter dizisi olarak sunulduğunda özelleştirilmiş bir çıktı
sağlayabilmek için __toString() yöntemi geçersiz kılınabilir.
İstisnaların kopyaları yapılamaz. Bir istisnanın kopyasını yapmaya çalışmak ölümcül
hatayla (E_FATAL seviyesinden bir hata) ile sonuçlanır.
- Exception sınıfının genişletilmesi
code}]: {$this->message}\n";
}
public function customFunction() {
echo "Bu türdeki istisnalar için özelleştirilmiş işlev\n";
}
}
/**
* İstisnayı denemek için bir sınıf oluşturalım
*/
class TestException
{
public $var;
const THROW_NONE = 0;
const THROW_CUSTOM = 1;
const THROW_DEFAULT = 2;
function __construct($avalue = self::THROW_NONE) {
switch ($avalue) {
case self::THROW_CUSTOM:
// özelleştirilmiş istisna oluştur
throw new MyException('1 geçersiz bir bağımsız değişkendir', 5);
break;
case self::THROW_DEFAULT:
// öntanımlı olarak bir oluşturulur.
throw new Exception('2 geçerli bir bağımsız değişken değildir', 6);
break;
default:
// İstisna yok; nesne oluşturulacak.
$this->var = $avalue;
break;
}
}
}
// Örnek 1
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) { // Yakalanacaktır
echo "Benim istisnam yakalandı\n", $e;
$e->customFunction();
} catch (Exception $e) { // Bu atlanır
echo "Öntanımlı istisna yakalandı\n", $e;
}
// Çalışmaya devam et
var_dump($o); // Null
echo "\n\n";
// Örnek 2
try {
$o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) { // Bu tür ile uyuşmuyor
echo "Benim istisnam yakalandı\n", $e;
$e->customFunction();
} catch (Exception $e) { // Bu yakalanacaktır
echo "Öntanımlı istisna yakalandı\n", $e;
}
// Çalışmaya devam et
var_dump($o); // Null
echo "\n\n";
// Örnek 3
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) { // Yakalanacaktır
echo "Öntanımlı İstisna yakalandı\n", $e;
}
// Çalışmaya devam et
var_dump($o); // Null
echo "\n\n";
// Örnek 4
try {
$o = new TestException();
} catch (Exception $e) { // Bu atlandır; istisna yok
echo "Öntanımlı İstisna yakalandı\n", $e;
}
// Çalışmaya devam et
var_dump($o); // TestException
echo "\n\n";
?>
]]>