Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Wyjątki - przewidywanie błedu, Po co rzucać błędem jeśli go przewidzieliśmy?
mimol
post
Post #1





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


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ć.
Go to the top of the page
+Quote Post
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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.

Ten post edytował Crozin 21.08.2012, 12:06:13
Go to the top of the page
+Quote Post
mimol
post
Post #3





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


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ł(IMG:style_emoticons/default/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?

Ten post edytował mimol 21.08.2012, 12:25:48
Go to the top of the page
+Quote Post
CuteOne
post
Post #4





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

Ostrzeżenie: (0%)
-----


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ć

Ten post edytował CuteOne 21.08.2012, 13:10:27
Go to the top of the page
+Quote Post
mimol
post
Post #5





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/wink.gif)

Po prostu będę musisał wyczuć tę granicę.
Go to the top of the page
+Quote Post
CuteOne
post
Post #6





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
mimol
post
Post #7





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


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??
Go to the top of the page
+Quote Post
CuteOne
post
Post #8





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/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

Ten post edytował CuteOne 21.08.2012, 19:58:53
Go to the top of the page
+Quote Post
mimol
post
Post #9





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

Ostrzeżenie: (0%)
-----


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() (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
pamil
post
Post #10





Grupa: Zarejestrowani
Postów: 97
Pomógł: 15
Dołączył: 12.08.2012
Skąd: Zabrze

Ostrzeżenie: (10%)
X----


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.
Go to the top of the page
+Quote Post
SmokAnalog
post
Post #11





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Wyjątki wymyślono po to, żeby ułatwić życie (IMG:style_emoticons/default/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.
Go to the top of the page
+Quote Post
irmidjusz
post
Post #12





Grupa: Zarejestrowani
Postów: 279
Pomógł: 60
Dołączył: 25.02.2012

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/biggrin.gif)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.12.2025 - 06:22