Forum und email

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";
?>