Kivételek (Exceptions)
A PHP 5 kivétel modellje hasonló más programozási nyelvekéhez. Egy kivételt dobhatunk (throw) és elkaphatunk (catch) a PHP-val. A kódot try blokkba kell tenni, hogy megkönnyítsük lehetséges kivétélek kezelését. Minden try blokknak rendelkezni kell legalább egy megfelelő catch blokkal. Többszörös catch blokkokat is használhatunk, így különböző osztályú kivételeket kaphatunk el. A program (ha nincs kivétel a try blokkban, vagy ha a kivétel nem illeszkedik egy catch blokkra sem) az utolsó catch blokk után folytatódik. Kivételek dobhatóak (throw) (vagy újradobhatóak) a catch blokkban.
Ha kivételt dobtunk, a blokkban a következő kód már nem fut le, és a PHP megkeresi az első catch blokkot, amire illeszkedik a kivétel. Ha a kivételt nem sikerült elkapni, a PHP fatális hibát (Fatal Error) ad ki "Uncaught Exception ..." szöveggel, hacsak nincs a set_exception_handler() beállítva.
Example#1 Kivétel küldése (throw Exception)
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Futás folytatása
echo 'Hello World';
?>
A fenti példa a következő kimenetet adja:
0.2 Division by zero. Hello World
Kivételek kiterjesztése
A felhaszánló is hozhat létre saját kivételeket, amiket a beépített Exception osztályra kell kiterjeszteni. A tagok és tuladonságok lejjebb megmutatják, mihez lehet hozzáférni az utód osztályban, amit a beépített Exception osztálytól örököl.
Example#2 A beépített Exception osztály
<?php
class Exception
{
protected $message = 'Unknown exception'; // kivétel üzenet
protected $code = 0; // felhasználó által megadott hibakód
protected $file; // kivétel forrásának fájlneve
protected $line; // kivétel forrásának sora
function __construct($message = null, $code = 0);
final function getMessage(); // hibaüzenet megszerzése
final function getCode(); // kivétel kódja
final function getFile(); // forrás fájl
final function getLine(); // forrás sor
final function getTrace(); // backtrace() tömb
final function getTraceAsString(); // formázott "trace" karakterlánc
/* Felülírható */
function __toString(); // formázott karakterlánc megjelenítéshez
}
?>
Ha az osztály utódja a beépített Exception osztálynak, és újradefinálja a konstruktort, erősen ajánlott, hogy meghívja a parent::__construct() metódust hogy biztosítsa, minden hozzáférhető adat helyesen legyen tárolva. A __toString() metódus úrjaírható, hogy tetszőleges legyen az objektum által prezentált karakterlánc.
Example#3 Exception osztály kiterjesztése
<?php
/**
* Saját kivétel osztály létrehozása
*/
class MyException extends Exception
{
// Újradefinálás, $message nem opcinális
public function __construct($message, $code = 0) {
// Kód...
// legyünk biztosak benne, hogy minden rendben tárolva
parent::__construct($message, $code);
}
// saját __toString() függvény
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "Saját függvény egy ilyen típusú kivételnek\n";
}
}
/**
* Osztály kivétel tesztelésére
*/
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:
// throw custom exception
throw new MyException('1 is an invalid parameter', 5);
break;
case self::THROW_DEFAULT:
// throw default one.
throw new Exception('2 isn\'t allowed as a parameter', 6);
break;
default:
// No exception, object will be created.
$this->var = $avalue;
break;
}
}
}
// 1. Példa
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) { // Elkapva
echo "Caught my exception\n", $e;
$e->customFunction();
} catch (Exception $e) { // Kihagyva
echo "Caught Default Exception\n", $e;
}
// Futás folytatása
var_dump($o);
echo "\n\n";
// 2. Példa
try {
$o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) { // Nem ez a típus
echo "Caught my exception\n", $e;
$e->customFunction();
} catch (Exception $e) { // Elkapva
echo "Caught Default Exception\n", $e;
}
// Futás folytatása
var_dump($o);
echo "\n\n";
// 3. Példa
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) { // Elkapva
echo "Default Exception caught\n", $e;
}
// Futás folytatása
var_dump($o);
echo "\n\n";
// 4. Példa
try {
$o = new TestException();
} catch (Exception $e) { // Ez nem kivétel
echo "Default Exception caught\n", $e;
}
// Futás folytatása
var_dump($o);
echo "\n\n";
?>