lutego 25
Wyjątki
Wyjątki to kolejne dobrodziejstwo PHP 5. Dzięki nim w wygodny sposób możemy obsługiwać i wywoływać błędy lub po prostu omijać zagnieżdzone instrukcje warunkowe.
Prosty przykład wykorzystania wyjątków
Mamy prosty kod – w założeniu chcemy by zmienna $login była nie pusta oraz żeby po pobraniu z bazy użytkownika o takim loginie hasło zapisane w zmiennej $haslo było równe temu zapisanemu w bazie.
Oto kod bez wykorzystania wyjątków:
-
else {
-
$res=mysql_query('SELECT `haslo` FROM uzytkownicy WHERE login="'.mysql_real_escape_string($login).'"');
-
else {
-
else {
-
/// logowanie itd.
-
}
-
}
-
}
Zauważamy, że instrukcji warunkowych, klamer jest tu bardzo wiele, a obsługa wyświetlania komunikatów i błędów jest bardzo utrudniona – dalsze instrukcje znowu trzeba zagnieżdzać.
Na ratunek przychodza wyjątki:
-
try{
-
-
$res=mysql_query('SELECT `haslo` FROM uzytkownicy WHERE login="'.mysql_real_escape_string($login).'"');
-
-
if($row['haslo']!=$haslo) throw new Exception('Niepoprawne hasło');
-
//logowanie
-
}
-
catch(Exception $e) {
-
}
Podany wyżej kod robi dokładnie to samo, ale nie ma tu nieskończonych instrukcji warunkowych, a dalsza manipulacja kodem jest ułatwiona.
Jak działają wyjątki?
Otóż zaobserwowaliście z pewnością, że kod jest objęty w blok „try”. Otóż blok „try” czuwa nad wyłapywaniem wyjątku – jeżeli wyrzucilibyśmy wyjątek poza blokiem try wyświetlił by się nam php error.
Następna nowość to instrukcja „throw” - rzucać – otóż wyjątki się wyrzuca a blok „catch” ma za zadanie je złapać, ale o tym zaraz. Po throw następuje utworzenie obiektu Exception – jest to standardowy obiekt wyjątków, po którym wszystkie inne dziedziczą. Podczas gdy wyjątek zostanie wykonany parser omija dalszy kod, az do końca bloku try.
Konstruktor Exception przyjmuje 2 argumenty – pierwszy to komunikat wyjątku, a drugi to kod. Oba argumenty są opcjonalne, więc nie musimy ich podawać. Poza tym obiekt dysponuje kilkoma funkcjami:
- getMessage() - zwraca komunikat wyjątku
- getCode() - zwraca kod wyjątku
- getLine() - zwraca linię pliku, w którym wystapił wyjątek
- getFile() - zwraca nazwę pliku, w którym wystapił wyjątek
- getTrace() - zwraca tablicę trace
- getTraceAsString() - zwraca tablice trace w formie ciągu
- __toString(); - jest to metoda specjalna, wywoływana przy probuje wyświetlenia wyjątku, a właściwie kazdego obiektu – echo $e;
Powyższe właściwości niezwykle przydadzą się nam przy łapaniu wyjątków w bloku „catch”. Do tego właśnie bloku trafia złapany wyjątek – możemy nim swobodnie manipulować. W naszym wypadku chcieliśmy złapać wyjątek klasy Exception, którego przypisaliśmy do zmiennej $e. Nastepnie wyświetliliśmy jego komunikat za pomocą metody getMessage().
Klasy wyjątków
W PHP 5.0 wbudowany był jedynie wyjątek klasy Exception. W PHP 5.1 mamy do dyspozycji takie klasy jak:
- LogicException
- BadFunctionCallException
- BadMethodCallException
- DomainException
- InvalidArgumentException
- LengthException
- OutOfRangeException
- RuntimeException
- OutOfBoundsException
- OverflowException
- RangeException
- UnderflowException
Poza tym możemy tworzyć własne klasy wyjątków, rozszerzając klase Exception.
-
class wyjatek extends Exception{
-
public function __toString() {
-
return 'Nastapił wyjątek w pliku '.$this->getFile().' w linii '.$this->getLine().' o treści: '.$this->getMessage();
-
}
-
}
Jak pewnie zauważyliście nadpisaliśmy magiczną metodę __toString, by w przystepnym dla nas języku mogła zwrócić dane wyjątku do wyświetlenia. Pamiętajmy, że __toString() oraz __construct() (konstruktor) są jedynymi metodami klasy Exception, które możemy rozszerzyć! Gdy spróbujemy tego z innymi dostaniemy piękny fatal error :-).
Teraz możemy wykorzystać nasz wyjątek:
Zauważyliście pewnie, że teraz użyliśmy dwóch bloków catch – dzieje się tak dlatego, że chcemy wykorzystać i nasz wyjątek i domyslną klasę wyjątku.
Jeżeli wystąpi wyjątek klasy Exception ominie on pierwszy blok catch, gdyż Exception nie jest obiektem klasy wyjatek. Wykona się zatem drugi blok. Jezeli jednak wyrzucimy wyjątek klasy wyjatek uruchomi się pierwszy blok, który łapie wyjątki tej klasy. Pamiętajmy, że jeden wyjątek może być złapany jedynie przez jeden blok catch!
Jednak co się stanie gdy nie napiszemy pierwszego bloku catch? :
-
try{
-
if($i%2!=0) throw new wyjatek('Ta liczba nie dzieli się przez 2!');
-
}
-
catch(Exception $e){
-
echo $e;
-
}
Okaże sie, że dalej wszystko działa – nie mamy fatala, jednak napis „Przechwyciliśmy nasz wyjątek!” się już nie wyświetla. Dlaczego tak się dzieje? Otóż znając pojęcie dziedziczenia klas wiemy, że klasa wyjatek dzidziczy po Exception, zatem obiekt klasy wyjatek jest również obiektem klasy Exception.
Popatrzmy na kolejny przypadek:
Niezależnie od tego jaki wyjątek wyrzucimy w tym przypadku wykona się pierwszy blok catch – wyjatek jest przecież rozszerzeniem klasy Exception!
Na koniec
Mam nadzieję, że przybliżyłem Wam temat wyjątków, i będziecie je odtąd wykorzystywać. Może to na początku wyglądać nieprzyjaznie, ale w praktyce takie nie jest – ja osobiście pluje sobie w brodę, że kiedyś ten temat olałem



