Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Wyjątki - przewidywanie błedu
Forum PHP.pl > Forum > Przedszkole
mimol
Czytałem coś o wyjątkach, wiem jak się ich używa, jednak nie mam pojęcia PO CO??
Patrząc na przykład z PHPEdia
  1. <?php
  2. class Foo {
  3. // $bar powinno być liczbą całkowita
  4. public function __construct($bar) {
  5. if (!is_int($bar)) {
  6. throw new InvalidArgumentException('Argument powinien być liczbę całkowitą!');
  7. }
  8.  
  9. echo 'Konstruktor wywołany z prawidłowym argumentem!';
  10. }
  11. }
  12.  
  13. try {
  14. $str = 'aaa';
  15. $foo = new Foo($str); // wywołujemy konstruktor klasy Foo z argumentem który jest stringiem
  16.  
  17. echo 'Obiekt klasy Foo został utworzony';
  18. } catch (Exception $e) {
  19. echo $e;
  20. }?>

Jaki sens ma łapanie tutaj wyjątku ?!
Czy nie lepiej jest
  1. if (!is_int($bar)) {echo '<p onclick="java script:histroy_back()">Argumen powinien być liczbą, Popraw dane</p>'}

Wyjątki wg mnie da się wrzucić TYLKO tam gdzie MOŻE POWSTAĆ błąd! Wieć czy nie lepiej jest pisać aplikacje tak BY NIE BYŁO błędów (przynajmniej tych o których wiemy że mogą być). Zgodnie z 'Lepiej zapobiegać niż leczyć'.
Proszę o jakieś wytłumaczenie po co ich używać.
Crozin
1. Co w przypadku gdybyś chciał zareagować na wystąpienie błędu inaczej niż zwykłym wywaleniem komunikatu i przerwaniem działania skryptu?
2. Zwykły komunikat błędu zawiera bardzo, bardzo mało informacji. Wyjątek może przenosić dowolnie złożoną strukturę danych, wyjątek może przechowywać zawierać w sobie przyczynę swojego wystąpienia (inny wyjątek), wyjątek posiada backtrace'a.
3. Wyjątki są mniej podatne na błędy i muszą być obsłużone na jakimś poziomie, inaczej przerwą działanie całego skryptu - zauważ, że w Twoim trywialnym przykładzie już popełniłeś błąd: wyświetlasz komunikat, ale pozwalasz na dalsze wykonywanie się kodu.

Cytat
Wyjątki wg mnie da się wrzucić TYLKO tam gdzie MOŻE POWSTAĆ błąd! Wieć czy nie lepiej jest pisać aplikacje tak BY NIE BYŁO błędów (przynajmniej tych o których wiemy że mogą być). Zgodnie z 'Lepiej zapobiegać niż leczyć'.
Jeżeli otrzymujesz informację o błędzie (nie koniecznie w postaci wyjątku) to znaczy, że ktoś przewidział ten błąd, ponieważ wiedział że może tam powstać błąd. Nie da się też napisać kodu pozbawionego obsługi błędów, który operuje na danych niezależnych od siebie. Nigdy nie wiesz czy dane otrzymane z zewnątrz są poprawne.
mimol
1. Co w przypadku gdybyś chciał zareagować na wystąpienie błędu inaczej niż zwykłym wywaleniem komunikatu i przerwaniem działania skryptu?
Sądze, że obojętnie czy 'sepcjalny komunikat' mogę również napisać zarówno z jak i bez wyjątków
2.Mógłbyś podać jakiś przykład
3. Jak napisać wyjątek, który nie przerwie działania skryptu, myślałem, że zawsze po wykonaniu instrukcji throw program kończy działanie?

Czy podsumowując wyjątki stosować tylko do skomplikowanych rzeczy (tam gdzie potrzebujemy jakiejś informacji jak błąd powstałquestionmark.gif) Bo nie widze sensu stosowania wyjątków w przykładnie powyżej

Cytat
Jeżeli otrzymujesz informację o błędzie (nie koniecznie w postaci wyjątku) to znaczy, że ktoś przewidział ten błąd, ponieważ wiedział że może tam powstać błąd. Nie da się też napisać kodu pozbawionego obsługi błędów, który operuje na danych niezależnych od siebie. Nigdy nie wiesz czy dane otrzymane z zewnątrz są poprawne.

Czyli wyjątki stosować tylko tam gdzie dane pochodzą od użytkownika?
CuteOne
Z życia wzięte
  1. $array = array('moj_config'=>'aaa');
  2. $navigation = new Zend_Navigation($array);

Wywali wyjątek o tym, że Zend_Navigation przyjmuje tylko obiekt z interfacem Zend_XXX. A gdy używasz tej klasy nagminnie to wiesz dokładnie, w którym pliku a co ważniejsze, w którym momencie pojawił się błąd.

Powiedzmy sobie szczerze
  1. echo 'cOś jesT tu nie tak';die();

jest lekko mówiąc mniej profesjonalne niż
  1. throw new XXX_Exception('cOś jesT tu nie tak');


Co do ostatniego pytania - nie. Pracując w grupie nad jednym projektem, wyjątki stają się wybawieniem od monotonnego szukania błędu. Jeżeli nie pracujesz w grupie to i tak ich używaj... zapobiegną szukaniu błędów w przyszłości gdy zechcesz coś modyfikować
mimol
dzięki za przykłady, chyba będę musiał więcej poćwiczyć, żeby czuć kiedy używać te wyjątki

Kod
echo 'cOś jesT tu nie tak';die();
throw new XXX_Exception('cOś jesT tu nie tak');

Pewnie jest mniej profesjonalne, ale nie widzę sansu w kodzie
....
np jakiś łatwy kaluklator i w funkcji dziel (używania wyjątków [dzielenie przez 0]) przecież dużo prościej,szybciej, czytelniej jest napisanie zwyklego nie dziel przez 0 wink.gif

Po prostu będę musisał wyczuć tę granicę.
CuteOne
Mylisz wyjątki z walidacją. Wyjątki mają informować (programistę) o tym, że coś poszło nie tak w tym i w tym miejscu a nie wywalać błąd z pełnym backtrackiem gdy ktoś wpisze fhuw@^^.pl/dw zamiast poprawnego maila
mimol
Więc jeżeli programista wie, że błąd się może pojawić, dlaczego nie napisać kodu tak, aby błąd się nie pojawił.
Np. załóżmy klasyczny przykład id artykułu pobierane w gecie.
Oczywście user podaje string
1) zrobić $id = (int)$_GET['id']; //czyli użytwonik nie zobaczy ani błedu ani swojego newsa
2) sprawdzić czy $_Get['id'] jest intem a jeśli nie to wypisać podano zły parametr prosty if else
3) Obsłużyć to na wyjątkach??
CuteOne
Kolejny przykład
  1. $config = Zend_Config('sciezka/do/pliku/xxx.ini');


Zend_Config oczekuje, że podasz prawidłową ścieżkę do pliku konfiguracyjnego inaczej sypnie wyjątkiem. Programista oczywiście o ty wie(zazwyczaj haha.gif) i nie wstawi tam ścieżki do nie istniejącego pliku ale... co jeżeli walnie literówkę i np. zamiast /configs/config.ini wpisze /config/config.ini? Będzie ślęczał w kodze godzinami w poszukiwaniu błędu..

W jednej ze swoich aplikacji używam około 10 wywołań Zend_Config w najróżniejszych miejscach i jakoś nie widzi mi się przeczesywać setki tysięcy linii kodu aby znaleźć literówkę gdy mogę odczytać nazwę pliku, linię i cały backtrack prosto z monitora. Pamiętaj programista to tylko człowiek i popełnia błędy

Mam nadzieję, że powyższy przykład rozjaśnił ci co nieco smile.gif


co do Twojego pytania... wyjątki mają służyć programistom nie użytkownikom a to co podałeś to nadal walidacja - do tego są osobne mechanizmy
mimol
wyjątki mają służyć programistom , dzięki to rozjaśnia mi troche na temat wyjątków
Przecierz w PHP4 nie było wyjątków, i jeśli ktoś podawał złą ścieżkę, to wywalało błąd. Większość sprawdzała czy file_exist() biggrin.gif
Podsumowując wyjątków używami bo dostarczają wiecej informacji niż zwykłe if, else. I muszę postarać się nie mylić wyjątków z walidacja

Wielkie CuteOne dzięki za mozolną próbę wytłumaczenia mi tego smile.gif
pamil
Chciałbym Ci przypomnieć, że najnowsze PHP (5.4) zostało wydane w tym roku, 5.3 w 2009 roku, PHP5 w 2005 roku, a PHP4 w 2000 roku. Przez te dwanaście lat jednak głównie PHP, ale i wiele aspektów programowania uległo zmianie.
SmokAnalog
Wyjątki wymyślono po to, żeby ułatwić życie smile.gif na początku wydają się chaotyczne, ale są całkiem porządnie wymyślone. A cała zabawa powstała po to, żebyś mógł łatwo decydować co ma się dziać w wyniku niecodziennego działania skryptów, bo przecież nie każdy błąd jest końcem świata i nie zawsze chcemy wszystko przerwać, a jedynie daną grupę operacji.
irmidjusz
mimol, jeśli nie używasz wyjątków, to:

- albo aplikacja sama wywala się przez błędy, nad czym nie masz kontroli co zrobić i w jaki sposób (ewentualnie masz niewielkie możliwości); jeśli raportowanie błędów jest włączone, takie błędy plują na ekran bardzo brzydkie komunikaty pełne informacji, które ze względów bezpieczeństwa nie powinny być udostępniane publicznie, a jeśli raportowanie błędów jest wyłączone, to użytkownik może nawet zobaczyć... nic, czyli pusty ekran
- albo sam w bardzo prymitywny sposób próbujesz użytkownikowi wyświetlić komunikat, że coś jest źle - to coś jest zakodowane bezpośrednio w miejscu wystąpienia błędu, więc jeśli masz w aplikacji sto miejsc, w których mogą wystąpić błędy, to w stu miejscach piszesz podobny kod wyświetlania informacji o błędzie razem z kodem sprawdzającym, czy ten błąd może wystąpić; wyobraź sobie, że chcesz nagle zmienić sposób postępowania w takich sytuacjach - musisz zmienić sto fragmentów kodu
- albo kodujesz program tak, żeby udawał, że nie ma błędów, mimo, że one są, czyli robisz klienta w bambuko

Jeśli rzucasz wyjątki, to możesz każdy z nich złapać i obsłużyć w dowolnym miejscu programu, i takie miejsce może być nawet tylko jedno (to zależy od tego jak jest zaprojektowana architektura programu). W miejscu przechwycenia wyjątku decydujesz, co zrobić w takiej sytuacji i w jaki sposób. Wyjątki można także rozpoznawać (po klasie wyjątku, ale także na podstawie zwracanego kodu) i zależnie od tego podejmować różne potrzebne czynności. I tak jak Crozin napisał, każdy wyjątek dostarcza mnóstwa użytecznych informacji na temat przyczyn i okoliczności wystąpienia danego błędu, co jest nieocenioną pomocą przy wykrywaniu błędów i poprawianiu programu.

Wyjątki są po prostu absolutnie zajebiste i jeśli w to wątpisz, to usiądź i poczekaj, aż Ci przejdzie biggrin.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.