• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Try catch - użycie

Object Storage Arubacloud
0 głosów
413 wizyt
pytanie zadane 22 listopada 2018 w PHP przez marcolo Obywatel (1,530 p.)

Kiedy wykorzystywać wyjątki "try, catch", jakoś tego nie rozumiem bo przykłady jakie znalazłem sobie w internecie są dla mnie głupie.

Np.

function podziel($a, $b) {
    if($b == 0) {
        throw new Exception("Nie dzielimy przez zero!");
    }
        return $a/$b;
}

try {
    echo podziel(12, 0);
} catch (Exception $e) {
    echo $e->getMessage();
}

A ja zrobiłbym to p oprostu używając if-a

function podziel($a, $b) {
    if($b != 0) {    
        return $a/$b;
    } else {
        return 'Nie dzielimy przez zero';
    }
}

Więc kiedy używać?

2 odpowiedzi

+3 głosów
odpowiedź 22 listopada 2018 przez Arkadiusz Waluk Ekspert (287,950 p.)
wybrane 22 listopada 2018 przez marcolo
 
Najlepsza
Na tak prostym kodzie faktycznie, użycie tego ifa może być lekko "brzydsze", ale robi to samo i może nawet prościej. Choć kłóciłbym się o to, co zwraca funkcja podziel w drugim kodzie - stringa czy liczbę? Powinien być zadeklarowany typ zwracany gdy to możliwe, mamy PHP7 od dawna. Gdybyś nie robił echo podziel() tylko chciałbyś dalej to np. dodać to co? Musiałbyś sprawdzić czy tam jest string (zwrócony błąd) czy liczba którą można dodać. Niezbyt wygodne.

Znasz trochę OOP i MVC? Mam nadzieję że tak, to będzie łatwiej. Załóżmy tak: masz aplikację i prosty schemat: uruchamia się kontroler użytkowników, który wywołuje jakąś klasę nazwaną ogólnie serwisem użytkowników, a ten serwis ma metodę tworzącą i zwracającą nowego użytkownika. Masz też piękną podstronę z błędem 500, który trzeba pokazać jak coś się wysypie oraz dodatkowo zalogować dokładny błąd do logów systemu. Teraz zagadka: jak obsłużyć błąd, który wydarzy się w serwisie podczas tworzenia użytkownika? Widoki zwraca przecież kontroler, z serwisu nie ma jak. Zwrócić null/string z błędem z metody tworzącej użytkownika? No nie możemy bo metoda ma zwracać model użytkownika, nawet jakby nie zadeklarować typu zwracanego to bez sensu przecież. Zrobić w serwisie echo 'błąd'; exit();? Paskudne, jak mówiłem strona musi zwracać cały konkretny widok z błędem 500 a i jeszcze zalogować ten błąd! W każdym miejscu gdzie może się coś stać musiałbyś więc przeklejać kod generowania podstrony i logowania błędu.

Tu z pomocą przychodzą wyjątki. Rzucasz sobie taki w serwisie. Przy dobrze napisanym kodzie wystarczy zrobić tak, że w jednym miejscu złapiesz wszystkie wyjątki i raz napiszesz tam kod wyświetlający podstronę błędu czy logowanie treści błędu do logów. Co więcej, można tworzyć własne klasy wyjątków, co daje możliwość różnych reakcji na różne błędy i łapania ich w odpowiednich miejscach, w zależności od potrzeb. Każdy wyjątek może mieć też swój kod błędu, dodatkowo możesz z niego odczytać plik w jakim został rzucony wyjątek, linię w kodzie, trace (ścieżkę, jakie klasy po kolei co wywoływały dochodząc do tego błędu). Rzucenie wyjątku przerywa dalsze wykonywanie kodu, czyli np. to co masz dalej w metodzie już się nie wykona, nie trzeba żadnych warunków. Do tego jeszcze wyjątki są przecież klasą, można więc we własnym typie np. nadpisać konstruktor czy dodać metodę i wstawić tam własną potrzebną logikę (nie szalałbym tu za bardzo z jej ilością, ale choćby dostosowanie komunikatu błędu bez problemu).

Mam nadzieję, że trochę rozjaśniłem - na przykładzie tego typu chyba najprościej wytłumaczyć.
1
komentarz 22 listopada 2018 przez matizuu Obywatel (1,100 p.)

A właściwie, co powinien zadeklarować jako zwracany typ inta z tego dzielenia, czy stringa z elsa?

czyli

function podziel(int $a, int $b) : int {}

czy

function podziel(int $a, int $b) : string {}

 

1
komentarz 22 listopada 2018 przez Arkadiusz Waluk Ekspert (287,950 p.)

No właśnie o to chodzi, że zwracając raz stringa a raz inta (czy nawet float, bo dzielenie może dać przecież wynik z ułamkiem) nie może zadeklarować typu zwracanego w taki sposób, bo jeśli zadeklaruje jedno a zwróci drugie to interpreter wyrzuci błąd.

W tym przypadku jest to po prostu źle napisane, funkcja/metoda niech zwraca jeden typ, a błędy obsługuje właśnie wyjątkami. Gdy faktycznie jest jakaś wyższa konieczność, aby tak zrobić, to nie można wtedy zadeklarować normalnie typu. Można jedynie w ramach dodatku wspomóc się phpDocumentorem i zapisać coś w rodzaju:

/**
 * @param int $a
 * @param int $b
 * @return string|float
 */
function podziel(int $a, int $b)
{
    // ...
}
komentarz 22 listopada 2018 przez matizuu Obywatel (1,100 p.)

Przepraszam autora pytania, że trochę mu tutaj zmieniam temat :D

@Arkadiusz tak odrzucając na razie na bok wyjątki, po przerobieniu tego w taki sposób:

function podziel(int $a, int $b) : float {
    if($b != 0) {    
        return $a/$b;
    } else {
        echo 'Nie dzielimy przez zero';
    }
}

byłoby ok, czy przez wywołanie "echo podziel(15, 0);" nie może tak być, bo właściwie otrzymujemy "echo echo 'Nie dzielimy przez zero'"?

komentarz 22 listopada 2018 przez marcolo Obywatel (1,530 p.)
Dzięki za wyjaśnienie
1
komentarz 22 listopada 2018 przez Arkadiusz Waluk Ekspert (287,950 p.)

@matizuu, biorąc dokładnie ten kod, który podałeś najpierw pojawi się "Nie dzielimy przez zero" a później błąd, bo nie zwróciłeś nic z funkcji, która ma zwracać float. Gdybyś usunął zwracanie float to funkcja sama wyświetlałaby ten komunikat, a następnie nie zwracała nic, czyli robiłaby echo niczego, a więc prawdopodobnie nic dodatkowo by się nie stało - byłoby raz "Nie dzielmy przez zero". Co nie zmienia faktu, że nie ma sensu robić echo echo, a w ogóle samo wyświetlanie czegoś nagle w funkcji nie jest zbyt dobrym pomysłem :)

0 głosów
odpowiedź 22 listopada 2018 przez Mitop Użytkownik (700 p.)
Hej, wyobraź sobie sytuacje, że np. pobierasz dane od użytkownika i przypisujesz do inta. Tylko że użytkownik zamiast inta podał stringa no i takie coś już ciężko obsłużyć normalnymi warunkami. Dlatego z tego co wiem wyjątki działają na zasadzie tego, że aplikacja cofa się niejako w swoim działaniu i catch pozwala obsłużyć tego typu kryzysowe sytuację.

Podobne pytania

0 głosów
1 odpowiedź 579 wizyt
pytanie zadane 16 lutego 2019 w Java przez periedynek Obywatel (1,320 p.)
0 głosów
2 odpowiedzi 637 wizyt
pytanie zadane 3 lipca 2018 w Java przez periedynek Obywatel (1,320 p.)
0 głosów
1 odpowiedź 297 wizyt
pytanie zadane 24 maja 2018 w PHP przez OdsetekGlupoty Pasjonat (15,360 p.)

92,550 zapytań

141,392 odpowiedzi

319,520 komentarzy

61,935 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...