Wstęp

Wstęp – Jak posługiwać się podstawową klasę PEAR (destruktory, obsługa błędów)

Synopsis

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

Opis

Podstawowa klasa PEAR dostarcza standardową funkcjonalność wykorzystywaną przez większość klas PEAR. Normalnie nigdy nie tworzysz bezpośrednio nowej instacji klasy PEAR, lecz przez jej rozszerzanie.

Podstawowe cechy to:

  • request-shutdown object "destructors"
  • obsługa błędów

"destruktory" PEAR

Jeśli dziedziczysz PEAR w klasie NazwaKlasy, możesz zdefiniować w niej metodę _NazwaKlasy (nazwa klasy poprzedzona znakiem podkreślenia), która zostanie wywołana w chwili zakończenia żądania. Nie jest to destruktor w znaczeniu takim, że w momencie "usuwania" obiektu zostanie on wywołany, jednak PHP daje Ci możliwość wywołania funkcji callback w chwili zakończenia wywoływania skryptu. Zobacz przykład poniżej.

Ważne!

Aby destruktory działały poprawnie, musisz zainicjować klasę za pomocą operatora "=& new" tak jak w poniższym przykładzie:

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

Jeżeli używasz tylko "= new", obiekt zarejestrowany na liście obiektów PEAR będzie kopią obiektu powstałą w czasie wywołania kontruktora, i "destruktor" tej kopii zostanie wywołany przy obsłudze zakończenia żądania.

Obsługa błędów PEAR

Podstawowe klasy PEAR dostarczają również metodę obsługi bardziej złożonych błędów niż tylko wartość true/false lub wartość numeryczna. Reprezentacja błędu w PEAR jest obiektem będącym instancją klasy PEAR_Error, lub klasy dziedziczącej z PEAR_Error.

Jednym z kryteriów projektowych obsługi błędów przez PEAR jest to, żeby nie wymuszać określonego typu wyjścia na użytkowniku - powinien umożliwiać obsługę błędów bez jakiegokolwiek wyjścia, jeżeli jest to pożądane. Umożliwia to przyjazną obsługę błędów, również wówczas gdy format wyjściowy jest inny niż HTML (na przykład WML lub inny format XML).

Obiekt błędu może zostać skonfigurowany na wiele sposobów, takich jak wyświetlenie wiadomości błędu, wyświetlenie wiadomości błędu i zakończenie żądania, zgłoszenie błędu przy pomocy funkcji PHP trigger_error(), wywołanie funkcji zwrotnej, lub żadne z powyższych. Zwykle jest to ustalone w konstruktorze PEAR_Error, ale wszystkie parametry są opcjonalne, i możesz ustawić domyślne dla błęów generowanych przez każdy obiekt oparty o klasę PEAR. Zobacz również przyklstrok;ady błędu PEAR aby zobaczyć jak ich używać, oraz PEAR_Error w celu poznania szczegółów.

Przykłady

Poniższe przykłady pokazują jak używać "biednych, emulowanych destruktorów" PEAR do implementacji prostej klasy przychowującej zawartość pliku, pozwalającej dodawać dane do obiektu oraz zapisać dane z powrotem do pliku:

PEAR: emulowane destruktory

<?php
require_once "PEAR.php";

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

    function 
FileContainer($file)
    {
        
$this->PEAR(); // this calls the parent class constructor
        
$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++;
    }

    
// The "destructor" is named like the constructor
    // but with an underscore in front.
    
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("this ends up at the end of the file\n");

// When the request is done and PHP shuts down, $fileobj's
// "destructor" is called and updates the file on disk.
?>
"Destruktory" PEAR używają funkcji zwrotnych PHP (register_shutdown_function()), i w PHP < 4.1, nie możesz wyświetlić z nich czegokolwiek gdy PHP działa na serwerze www. Tak więc cokolwiek wypisane w "destruktorze" przepada, poza przypadkiem gdy PHP używane jest w trybie linii poleceń. W PHP 4.1 i wyższych, wyjście może być również generowane w destruktorze. Zobacz również ostrzeżenie dotyczące tego jak tworzyć instacje obiektów gdy chcesz użyć destruktora.

Następne przykłady ilustrują różne metody użycia mechanizmu obsługi błędów PEAR.

PEAR error example (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 error: ".$sock->getMessage()."\n";
}
?>

This example shows a wrapper to fsockopen() that delivers the error code and message (if any) returned by fsockopen in a PEAR error object. Notice that PEAR::isError() is used to detect whether a value is a PEAR error.

PEAR_Error's mode of operation in this example is simply returning the error object and leaving the rest to the user (programmer). This is the default error mode.

In the next example we're showing how to use default error modes:

PEAR error example (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 
"still alive\n";
?>

Here, we set the default error mode to PEAR_ERROR_DIE, and since we don't specify any error mode in the raiseError call (that'd be the third parameter), raiseError uses the default error mode and exits if fsockopen fails.

Global Variables Used

The PEAR class uses some global variables to register global defaults, and an object list used by the "destructors". All of the global variables associated with the PEAR class have a _PEAR_ name prefix.

$_PEAR_default_error_mode
If no default error mode is set in an object, this mode will be used. Must be one of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE or PEAR_ERROR_CALLBACK.

Don't set this variable directly, call PEAR::setErrorHandling() as a static method like this:

<?php
PEAR
::setErrorHandling(PEAR_ERROR_DIE);
?>
$_PEAR_default_error_options
If the error mode is PEAR_ERROR_TRIGGER, this is the error level (one of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).

Don't set this variable directly, call PEAR::setErrorHandling() as a static method like this:

<?php
PEAR
::setErrorHandling(PEAR_ERROR_TRIGGERE_USER_ERROR);
?>
$_PEAR_default_error_callback
If no options parameter is used when an error is raised and the error mode is PEAR_ERROR_CALLBACK, the value of this variable is used as the callback. This means that you can switch the error mode temporarily and return to callback mode without specifying the callback function again. A string value represents a function, a two-element array with an object at index 0 and a string at index 1 represents a method.

Again, don't set this variable directly, call PEAR::setErrorHandling() as a static method like this:

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

Oto przykład jak możesz przełaczać obsługę błędów bez ponownego określania funkcji obsługi błędu:

<?php
PEAR
::setErrorHandling(PEAR_ERROR_CALLBACK"my_function_handler");
do_some_stuff();
PEAR::setErrorHandling(PEAR_ERROR_DIE);
do_some_critical_stuff();
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK);
// now we're back to using my_function_handler again
?>