Bevezetés

Bevezetés – a PEAR alaposztály használata (destruktorok, hibakezelés)

Synopsis

require_once "PEAR.php";
class classname extends PEAR { ... }

Leírás

A PEAR alaposztály a legtöbb PEAR csomag által használt funkcionalitásokat nyújtja. Alapesetben a leszármazottait használjuk, soha nem hozunk létre példányokat közvetlenül a PEAR osztályból.

Az osztály legfőbb szolgáltatásai a következők:

  • objektumok destruktorának automatikus meghívása a szkriptek lefutása után
  • hibakezelés

PEAR "destruktorok"

Ha egy osztályt a PEAR osztályból származtatunk, (legyen az osztály neve például ClassName), definiálhatunk benne egy metódust _ClassName néven (az osztály neve egy hangosközzel bevezetve), ami automatikusan meghívásra fog kerülni a kérés lefutása után. Ez nem egy "valós" destruktor, mivel ha egy objektumot "törlünk", a destruktorban megadott kód nem fog lefutni. A PHP hívja meg a destruktort, ha végzett a futtatással. Lásd az alábbi példát.

Fontos!

A destruktorok megfelelő működéséhez az osztályt az "=& new" operátorral kell létrehozni, a következő módon:

<?php
$obj 
=&amp; new MyClass();
?>

Ha csak "= new" -t használnánk, a PEAR shutdown-listájában regisztrálásra kerülő objektum csak az eredeti objektum egy másolata lenne (a létrehozás utáni állapotban), és ennek a másolatnak a destruktora kerülne meghívásra a kérés lefutása után.

PEAR hibakezelés

A PEAR alaposztály lehetővé teszi, hogy sokkal komplexebb hibákkal térjünk vissza, mint egy egyszerű true/false érték, vagy hibakód. A PEAR-ben keletkező hiba mindig egy objektum, ami a PEAR_Error osztálynak, vagy egy leszármazottjának egy példánya.

A PEAR hibaobjektumainak egyik tervezési kritériuma volt, hogy egy bekövetkező hiba se kerüljön automatikusan kiírásra a felhasználónak, minden hibának lekezelhetőnek kell lennie anélkül, hogy bármilyen kimenete lenne. Ez teszi lehetővé a hibák elegáns kezelését, akkor is, ha a kimeneti formátum nem HTML (például WML, vagy más XML formátum).

A hibaobjektum többféleképpen konfigurálható - több dolgot is csinálhat létrehozásakor, például kiírhat egy hibaüzenetet, kiírhatja a hibaüzenetet és kiléphet, kiválthat egy hibát a PHP trigger_error() függvényével, meghívhat egy callback fügvényt, vagy a fentiek közül mindegyiket elhagyhatja. A kívánt viselkedést tipikusan a PEAR_Error konstruktorában specifikáljuk, de minden paraméter opcionális, és beállíthatunk alapértelmezett értékeket is, amelyek érvényesek lesznek minden objektumra, ami a PEAR osztályon alapul. Lásd a "PEAR error" példák című fejezetet a használat megértéséhez és a PEAR_Error referenciát a részletekhez.

Példák

Az alábbi példa bemutatja, hogyan használhatjuk a PEAR emulált destruktorait egy egyszerű osztály megvalósításához, ami egy fájl tartalmát tárolja, hozzá tud fűzni adatot az objektumhoz, és visszaírja az adatot a fájlba a kérés végén:

PEAR: emulált destruktorok

<?php
require_once "PEAR.php";

class 
FileContainer extends PEAR
{
    var 
$file '';
    var 
$contents '';
    var 
$modified 0;

    function 
FileContainer($file)
    {
        
$this->PEAR(); // sz&uuml;l&#337; oszt&aacute;ly konstruktor&aacute;nak megh&iacute;v&aacute;sa
        
$fp fopen($file"r");
        if (!
is_resource($fp)) {
            return;
        }
        
$this->file $file;
        while (
$data fread($fp2048)) {
            
$this->contents .= $data;
        }
        
fclose($fp);
    }

    function 
append($str)
    {
        
$this->contents .= $str;
        
$this->modified++;
    }

    
// A "destruktor" neve ugyanaz mint a konstruktor&eacute;,
    // de egy hangosk&ouml;z vezeti be.
    
function _FileContainer()
    {
        if (
$this->modified) {
            
$fp fopen($this->file"w");
            if (!
is_resource($fp)) {
                return;
            }
            
fwrite($fp$this->contents);
            
fclose($fp);
        }
    }
}

$fileobj =&amp; new FileContainer("testfile");
$fileobj->append("ez beker&uuml;l a f&aacute;jl v&eacute;g&eacute;re\n");

// Amikor a k&eacute;r&eacute;s lefutott &eacute;s a PHP le&aacute;llna, a $fileobj
// "destruktora" megh&iacute;v&aacute;sra ker&uuml;l &eacute;s fel&uuml;l&iacute;rja a f&aacute;jlt a lemezen.
?>
A PEAR "destruktorai" a PHP shutdown callback-jeit használják (register_shutdown_function()). A PHP < 4.1 verzióiban nem írhatunk a kimenetre belőlük ha webszerveren futtatjuk a kódot. Bármi, ami a "destruktor"-ban kiírásra kerül, elvész, kivéve, ha a PHP-t parancssori módban használjuk (CLI). PHP 4.1-ben és afölött már a destruktor is generálhat kimenetet. Ezen kívül lásd a figyelmeztetést arról, hogy hogyan kell létrehozni az objektumokat amennyiben használni szeretnénk a konstruktorukat.

A következő példák illusztrálják a PEAR hibakezelési mechanizmusának különböző lehetséges módjait.

"PEAR error" példa (1)

<?php
function mysockopen($host "localhost"$port 8090)
{
    
$fp fsockopen($host$port$errno$errstr);
    if (!
is_resource($fp)) {
        return new 
PEAR_Error($errstr$errno);
    }
    return 
$fp;
}

$sock mysockopen();
if (
PEAR::isError($sock)) {
    print 
"mysockopen hiba: ".$sock->getMessage()."&lt;BR&gt;\n"
}
?>

Ez a példa egy wrapper az fsockopen() függvényhez, amely az fsockopen által visszaadott hibakódot és hibaüzenetet "csomagolja be" egy PEAR hibaobjektumba. Figyeljük meg, hogy a PEAR::isError() függvényt használjuk annak vizsgálatára, hogy az objektum egy PEAR hibaobjektum-e.

A PEAR_Error működési módja ebben a példában egyszerűen a hibaobjektum visszaadása, a többi a felhasználóra (fejlesztő) marad. Ez az alapértelmezett mód.

A következő példákban bemutatjuk, hogyan használjuk az alapértelmezett módokat:

"PEAR error" példa (2)

<?php
class TCP_Socket extends PEAR
{
    var 
$sock;

    function 
TCP_Socket()
    {
        
$this->PEAR();
    }

    function 
connect($host$port)
    {
        
$sock fsockopen($host$port$errno$errstr);
        if (!
is_resource($sock)) {
            return 
$this->raiseError($errstr$errno);
        }
    }
}

$sock = new TCP_Socket;
$sock->setErrorHandling(PEAR_ERROR_DIE);
$sock->connect('localhost'8090);
print 
"nem &aacute;llt le a fut&aacute;s, sikeres a csatlakoz&aacute;s&lt;BR&gt;\n";
?>

Itt először beállítjuk az alapértelmezet módot a PEAR_ERROR_DIE-ra, és mivel nem adunk meg semmilyen egyéb módot a raiseError hívásban (harmadik paraméterként), ezért a raiseError az alapértelmezett hibamódot alkalmazza és megállítja a szkript futását, ha az fsockopen hibával tér vissza.

Felhasznált globális változók

A PEAR osztály néhány globális változót használ a globális alapértelmezések és egy objektumlista tárolására (utóbbit a destruktorok kezeléséhez). Minden globális változó amely a PEAR osztállyal áll kapcsolatban, a _PEAR_ prefixet kapta.

$_PEAR_default_error_mode
Ha nincs alapértelmezett mód beállítva egy objektumon belül, ez a mód lesz érvényes. A következő konstansok egyikének kell lennie: PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE or PEAR_ERROR_CALLBACK.

Ne állítsuk ezt a változót közvetlenül, hívjuk helyette a PEAR::setErrorHandling() metódust statikusan, a következőképpen:

<?php
PEAR
::setErrorHandling(PEAR_ERROR_DIE);
?>
$_PEAR_default_error_options
Ha a hibamód PEAR_ERROR_TRIGGER, ez a kiváltandó hiba szintje (lehetséges értékei E_USER_NOTICE, E_USER_WARNING vagy E_USER_ERROR).

Ne állítsuk a változó értékét közvetlenül, hívjuk helyette a PEAR::setErrorHandling() metódust statikusan, a következőképpen:

<?php
PEAR
::setErrorHandling(PEAR_ERROR_TRIGGERE_USER_ERROR);
?>
$_PEAR_default_error_callback
Ha nem használjuk az options paramétert hiba kiváltásakor és a hibamód PEAR_ERROR_CALLBACK, akkor ennek a változónak az értéke lesz callback-ként használatos. Ez azt jelenti, hogy ideiglenesen megváltoztathatjuk a hibamódot, és visszatérhetünk callback módra anélkül, hogy a függvényt újból meg kellene neveznünk. Sztring típusú értékkel hivatkozhatunk egy függvényre, míg egy kétdimenziós tömb egy objektummal (0-s index) és egy sztringgel (1-es index) egy objektum egy metódusát jelenti.

Ne állítsuk a változó értékét közvetlenül, hívjuk a PEAR::setErrorHandling() metódust statikusan, a következőképpen:

<?php
PEAR
::setErrorHandling(PEAR_ERROR_CALLBACK"sajat_hibakezelo_fuggveny");
?>

A következő példa szemlélteti, hogyan kapcsolgathatunk oda-vissza a callback függvény újbóli megadása nélkül:

<?php
PEAR
::setErrorHandling(PEAR_ERROR_CALLBACK"sajat_hibakezelo_fuggveny");
csinalj_valamit();
PEAR::setErrorHandling(PEAR_ERROR_DIE);
csinalj_valami_kritikus_dolgot();
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK);
// a tov&aacute;bbiakban hiba eset&eacute;n ism&eacute;t a sajat_hibakezelo_fuggveny ker&uuml;l majd megh&iacute;v&aacute;sra
?>