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:
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 =& 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.
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.
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ülő osztály konstruktorának meghívása
$fp = fopen($file, "r");
if (!is_resource($fp)) {
return;
}
$this->file = $file;
while ($data = fread($fp, 2048)) {
$this->contents .= $data;
}
fclose($fp);
}
function append($str)
{
$this->contents .= $str;
$this->modified++;
}
// A "destruktor" neve ugyanaz mint a konstruktoré,
// de egy hangoskö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 =& new FileContainer("testfile");
$fileobj->append("ez bekerül a fájl végére\n");
// Amikor a kérés lefutott és a PHP leállna, a $fileobj
// "destruktora" meghívásra kerül és felülírja a fá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()."<BR>\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 állt le a futás, sikeres a csatlakozás<BR>\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.
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.
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);
?>
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_TRIGGER, E_USER_ERROR);
?>
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ábbiakban hiba esetén ismét a sajat_hibakezelo_fuggveny kerül majd meghívásra
?>