Witaj, Gościu O nas | Kontakt | Mapa
Wortal Forum PHPEdia.pl Planeta Kubek IRC Przetestuj się!

Projektowanie aplikacji w PHP. Część druga.

Obsługa błędów.

Naszym następnym tematem dyskusji będzie obsługa błędów. Temat jest bardzo obszerny, ale dla naszych potrzeb zapoznamy się tylko z podstawami. Obsługa błędów powinna być "elegancka" w każdej aplikacji - to znaczy, że system sam powinien wiedzieć jak wykrywać błędy i obsłużyć je w odpowiedni sposób, przy minimalnym zakłócaniu swojej pracy. Może się to wydać dziwne, ale programiści PHP mają tendencję do nadmiernego komplikowania omawianej obsługi błędów - objawia się to w gromadzeniu dodatkowych informacji o błędach, które tak naprawdę nie są nikomu potrzebne. Poniższy przykład demonstruje prostą klasę błędu.

<?php
class Error 
{
 var $number;
 var $string;
 var $file;
 var $line;
 function setError($number, $string, $file, $line) 
 {
  $this->number = $number;
  $this->string = $string;
  $this->file = $file;
  $this->line = $line;
  $this->showError();
 }
function showError()
{
 print 'Error ('.$this->code.'): '.$this->message."<br />
".$this->file.' ('.$this->line.')<br />';
}
}
?>

Ta prosta klasa pobiera informacje o błędzie przy użyciu metody "setError", a wyświetla je przy pomocy metody "showError". Metody te są ściśle ze sobą związane. Chociaż klasa nie raczej nie nadaje się do eleganckiej obsługi błędów, stanowi podstawę przechwytywania i wpływania na format informacji wyświetlanych po zaistnieniu błędu.

Ustawienie naszego tworu jako klasy obsługującej błędy jest dosyć proste. Rozważ poniższy przykład:

<?php
$errorHandler = &new Error();
set_error_handler(array(&$errorHandler, 'setError'));
?>

Dzięki temu, każdy zaistniały błąd zostanie przesłany do funkcji Error::setError(). Przyjrzyj się kolejnemu przykładowi, w którym skrypt próbuje połączyć się z jedną z baz danych i w razie niepowodzenia generuje błąd. Ustawienia dotyczące bazy zostały bezpośrednio włączone do skryptu. Przyjmijmy, że plik "class.error.php" znajduje się w domyślnej ścieżce dołączania i zawiera naszą klasę obsługującą błąd.

<?php
$settings['db'][0]['user'] = 'someuser';
$settings['db'][0]['pass'] = 'password';
$settings['db'][0]['host'] = '192.168.1.2';
$settings['db'][0]['name'] = 'MyApp';
$settings['db'][1]['user'] = 'root';
$settings['db'][1]['pass'] = 'password';
$settings['db'][1]['host'] = '192.168.1.120';
$settings['db'][1]['name'] = 'MyApp';

$settings['db'][2]['user'] = 'root';
$settings['db'][2]['pass'] = '';
$settings['db'][2]['host'] = 'localhost';
$settings['db'][2]['name'] = 'MyApp';
require_once('class.error.php');
$errorHandler = &new Error();
set_error_handler(array(&$errorHandler, 'setError'));
$dbh = false;
$try = 0;
do 
{
 $dbh = @mysql_connect($settings['db'][$try]['host'], 
       $settings['db'][$try]['user'], 
        $settings['db'][$try]['pass']);
$try++;
} while (($dbh === false) && ($try < count($settings['db'])));
if ($dbh === false) 
{
 trigger_error('Unable to connect to database.', E_USER_ERROR);
}
?>

W przedstawionym przykładzie mamy 2 dostępne hosty, do których próbujemy się podłączyć przy pomocy "mysql_connect". Takie rozwiązanie samo w sobie jest już jakby obsługą błędów - nasza aplikacja próbuje nawiązać alternatywne połączenie, zanim całkowicie nawali. Jeśli nie uda się nawiązać żadnego połączenia, skrypt wygeneruje błąd krytyczny.

W zwykłym skrypcie nieudane połączenie z bazą spowodowałoby wygenerowanie błędu typu Warning, ale wiedząc że nasza aplikacja wymaga tegoż połączenia, wykonywanie skryptu zostaje przerwane. Można by było tak skonfigurować naszą obsługę błędów, aby błędy przechodziły do obiektów na najwyższym poziomie, które mają za zadanie zastopować skrypt i odpowiednio wyświetlić powiadomienie o błędzie. Moglibyśmy także rozszerzyć naszą klasę, aby odpowiednie rodzaje błędów przesyłała do odpowiednich podklas.

W PHP5 obsługa błędów jest jeszcze potężniejsza dzięki wyjątkom i blokom try/catch, które pozwalają projektantom na stworzenie własnego typu wyjątku dla każdego obiektu czy nawet każdej akcji, dostosowując w ten sposób przydatność informacji dostarczonych przez wyjątki, a także wyraźnie oddzielić kod obsługujący błędy od zwykłych implementacji algorytmów. Ponieważ ten artykuł ma przedstawiać problem niezależnie od wersji PHP, a powyższe przykłady działają także pod PHP5, nie będę przedstawiał przykładu użycia wyjątków, aczkolwiek założenia są te same.

Obsługa błędów jest naprawdę bardzo szerokim zagadnieniem, a przedstawione przykłady to tylko malutka część problemu. Dodatkowo, obsługa błędów często posiada bardzo wąski zakres i jako programista, sam musisz użyć swojego doświadczenia w rozwiązywaniu problemów i zdecydować, jakie opcje powinny być dostępne dla twojej obsługi i jak obsłużyć błędy możliwie najwydajniej i najefektywniej.

Jednym z najważniejszych aspektów podczas tworzenia domniemanej obsługi błędów jest zdolność przechwytywania prawdziwych błędów, generowanych podczas rzeczywistego użycia aplikacji. To pozwala projektantom być na bieżąco z błędami w systemie, nawet tymi, których nie przewidziano podczas tworzenia oprogramowania. I w tym miejscu pojawia się problem - skąd programiści mają wiedzieć, jakie błędy pojawiają się podczas korzystania z aplikacji? Rozwiązanie jest jedno: Logowanie.

Informacje na podobny temat:
Wasze opinie
Wszystkie opinie użytkowników: (1)
...
Wtorek 15 Styczeń 2008 12:28:08 am - plurr

bardzo ciekawy artykul, czekam z niecierpliwoscia na obiecana nastepna czesc :)

pozdr.

Mentax.pl    NQ.pl- serwery z dodatkiem świętego spokoju...   
O nas | Kontakt | Mapa serwisu
Copyright (c) 2003-2017 php.pl    Wszystkie prawa zastrzeżone    Powered by eZ publish Content Management System eZ publish Content Management System