![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 21 Pomógł: 1 Dołączył: 6.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
Witam. Chciałem się dowiedzieć, kiedy NALEŻY stosować wyjątki w OOP? Chodzi mi o konkretne przykłady i jakieś dobre wytłumaczenie.
Wyjątki jak sama nazwa wskazuje, ale np . Kod $a=5; $b=0; if($a<$5){ ... } Też mogli byśmy użyć wyjątków? i czy powinno się? bless |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 580 Pomógł: 85 Dołączył: 25.03.2010 Skąd: Skrzyszów :) Ostrzeżenie: (0%) ![]() ![]() |
Przeanalizuj ten kod, to powinno Ci się rozjaśnić, wyjątki znacznie upraszczają tworzenie aplikacji, nie musisz wszystkiego if'ować żeby się upewnić ze watrość jest ok |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 21 Pomógł: 1 Dołączył: 6.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
No tak, ale czy zamiast
Kod function getDb() { $database = mysqli(); if(!$database) throw new Exception('xxx'); } damy Kod function getDb() { $database = mysqli(); if(!$database) echo "Komunikat"; exit; } Dlatego czemu powinno się używać wyjątków? |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 952 Pomógł: 154 Dołączył: 20.01.2007 Skąd: /dev/oracle Ostrzeżenie: (0%) ![]() ![]() |
Wyjątki nie należą do programowania obiektowego. W wielu językach wyjątkiem może być cokolwiek - liczba, tekst, obiekt... jedyna rzecz wspólna z OOP w PHP to właśnie wymóg, że wyjątek musi być obiektem mającym gdzieś klasę Exception.
Trochę praktycznych przykładów dotyczących wyjątków jest tutaj: http://pl.wikibooks.org/wiki/PHP/Wyjątki Wyjątki rozwiązują następujący problem: w jakiejś funkcji powstał błąd, ale czy dla tego, kto ją wywołał, jest on krytyczny czy nie? Co więcej - czy na błąd reagować ma ten, kto funkcję wywołał czy jakiś nadrzędny strażnik? Aby zaprogramować to przy pomocy ifów, funkcji itd. musiałbyś się sporo naklepać. Zamiast tego, po prostu rzucasz wyjątek. Ktoś "u góry" musi go odebrać i zdecydować, co z nim robić. Jako przykład może posłużyć jakaś biblioteka umożliwiająca chodzenie po katalogach. Chcemy utworzyć plik w jakimś katalogu, więc wywołujemy funkcję createFile(). Jednak okazało się, że dany katalog nie istnieje, dlatego funkcja rzuca nam wyjątek. Jeśli realizujemy polecenie użytkownika "utwórz plik", możemy właśnie teraz zdecydować, że w tym przypadku błąd jest krytyczny i poinformować go o tym. Ale przecież createFile() może być wywoływana przez inną funkcję biblioteki, która przy okazji musi stworzyć plik, a jeśli się nie uda, zająć się czymś innym. Tym razem otrzymanie wyjątku nie oznacza błędu krytycznego. Dlatego robimy: Kod try { createFile(); robA(); } catch(Exception $wyjatek) { robB(); } I zupełnie nie zajmujemy się treścią wyjątku, ponieważ on służy nam jedynie do dowiedzenia się, że pliku nie da się utworzyć (np. już istnieje), więc możemy to olać i zająć się dalszą częscią zadania. W swoim kodzie wyjątki rzucam wszędzie tam, gdzie stwierdzam, że jest coś, czego nie powinno być, albo na odwrót - nie ma czegoś, co być powinno. Każde odstępstwo od spodziewanego w danym miejscu stanu jest raportowane w ten sposób (wbrew pozorom nie ma tego tak dużo, a już na pewno nie prowadzi to do sytuacji, gdy na 1000 linijek 500 to instrukcje throw ![]() -------------------- Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0 |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 21 Pomógł: 1 Dołączył: 6.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
Wiem że nie należy, ale zazwyczaj używa się ich w OOP z tego co czytałem.
Ok już rozumiem jak to działa, tylko nadal nurtuje mnie to, kiedy używać wyjątków a kiedy po prostu zwykłych funkcji warunkowych.. |
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
To zrob eksperyment:
raz uzywaj zwyklych IF a raz uzywac wyjątków. Napisz w ten sposob jeden projekt a sam stwierdzisz co ci wygodniej. -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#7
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Jak sama nazwa mówi, wyjątki powinno się stosować w sytuacjach możliwego, nietypowego zachowania skryptu. Niektórzy stosują to rozwiązanie jako swego rodzaju strukturę kontrolną, ale to moim zdaniem nadużywanie. Jako że często to jest stosowana rzecz w C++ i Javie to tutoriale tych języków tyczące najczęściej w najprostszy i najbardziej przystępny sposób stosowanie wyjątków opisują. Tam pojawią się zresztą nie tylko throw, try, catch, ale choćby rethrow, które także z wyjątkami jest związane.
-------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#8
|
|
![]() Grupa: Zarejestrowani Postów: 21 Pomógł: 1 Dołączył: 6.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
W przypadku np. połączenia z baza danych i połączenie nie wykona się poprawnie powinno się
np. użyć wyjątków, tak? a jak się validuje dane od użytkownika i np. sprawdza się czy zmienne nie są puste, to wystarczy użyć f. warunkowej? |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 580 Pomógł: 85 Dołączył: 25.03.2010 Skąd: Skrzyszów :) Ostrzeżenie: (0%) ![]() ![]() |
Tak, błąd przy wprowadzaniu danych od użytkownika nie jest sytułacją wyjątkową, więc wyjątki są nie na miejscu lepiej if'ować.
Natomiast gdybyś nie mógł odczytać danych z katalogu (co zawsze powinno się udać) najlepiej zastosować wyjątki. Sama teoria niewiele Ci da, sam musisz zaczą pisać, to zrozumiesz kiedy używać wyjątków a kiedy if'ować Ten post edytował zend 31.03.2010, 15:42:55 |
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 21 Pomógł: 1 Dołączył: 6.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
zend dziękuje:) Posłucham się i poćwiczę
![]() Pozdrawiam Na podstawie waszych odpowiedzi, napisałem klasę do tworzenia miniatur. Proszę o ocenę skryptu:) Napiszcie co można poprawić itd. Za odpowiedzi dziękuje:) Kod <?php //Autor: Podgur class ImageException extends Exception { public function __toString() { $ret = 'Powstal blad<br /> Komunikat: '.$this->getMessage().'<br />Plik: '.$this->getFile().'<br />Wiersz: '.$this->getLine(); return $ret; } } class ImageClass { public $image; //konstruktor pobierający obrazek function __construct($url) { //Sprawdzanie czy istnieje plik graficzny podany w konstruktorze if(!file_exists($url)) { //W przypadku nie istnienia pliku throw new ImageException('Podany plik nie istnieje'); }else{ $this->image=$url; } } public function resize($height,$width,$quality=60) { //Brak obsługi formatu png i bmp //Pobranie nazwy pliku $namefile = $this->image; //Wycięcie rozszerzenia $type = substr(strstr($namefile,'.'),1); //Tablica z formatami $rozszerzenia=array("jpg","jpeg","gif"); if(!in_array($type,$rozszerzenia)) { throw new ImageException('Zly format pliku'); } //Nagłówek header("Content-Type: image/$type"); switch($type){ //Rozszerzenie *.jpg/jpeg case "jpg": $img = imagecreatefromjpeg($this->image); break; //Rozszerzenie *.gif case "gif": $img = imagecreatefromgif($this->image); break; } $mini = imagecreatetruecolor($width,$height); //Stworzenie miniatury imagecopyresized($mini,$img,0,0,0,0,$width,$height,imagesx($img),imagesy($img)); switch($type){ //Rozszerzenie *.jpg/jpeg case "jpg": imagejpeg($mini, "mini".rand(1,100)."_$namefile", 70); break; //Rozszerzenie *.gif case "gif": imagegif($mini, "mini".rand(1,100)."_$namefile", 70); break; } } } try { //wywolanie obiektu klasy. Jako parametr dajemy scieżke, bądź nazwę pliku $photo = new ImageClass('a.jpg'); //wywolanie metody resize() $photo->resize(1000,1000); //Przyjmuje 3 parametry: wysokosc,szerokosc i jakość miniatury } catch(ImageException $error) { echo $error; } ?> |
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Po co jakieś ImageException, które jedyne co robi to formatuje treść błędu (czego robić na dobrą sprawę nie powinno)? Co innego jeżeli byłoby to używane w celu wyłapania tego typu wyjątku w bloku catch, ale z tego co widzę to tutaj jedyny cel istnienia bloku catch, to wywalenie błędu.
Zamiast ImageException('Podany plik nie istnieje') wolałbym otrzymać wyjątek typu: IOException, w którym jako parametr byłby przekazany URL obrazka itp., niż bardzo niewygodną w dalszej obróbce informację "obrazek nie istnieje". Swoją drogą... nie stosuj zapisu typu: Wystarczy: Im mniej klamerek tym zazwyczaj lepiej. ImageClass::$image (to Class to sobie daruj) mogłoby być już "zasobem" (wynikiem imagecreateformXXX() lub czegoś w tym stylu (jeżeli nie korzystałbyś z biblioteki GD). Do pobrania rozszerzenia z ścieżki służy pathinfo Sprawdzaj czy aby przypadkiem wygenerowana nazwa pliku już nie istnieje. Po co nagłówek Content-Type, skoro plik tylko zapisujesz, a nie wyświetlasz? |
|
|
![]()
Post
#12
|
|
![]() Grupa: Zarejestrowani Postów: 21 Pomógł: 1 Dołączył: 6.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
Zaraz pozmieniam:) dzięki.
Jeżeli ktoś ma jeszcze jakieś uwagi,to zapraszam:) |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 2 Pomógł: 1 Dołączył: 19.02.2011 Ostrzeżenie: (0%) ![]() ![]() |
Postanowiłem mój pierwszy post, napisać właśnie w tym temacie. Może ktoś byłby mi w stanie rozjaśnić...
Czy w PHP istnieją jakieś standardowe funkcje rzucające wyjątki? Czy jest to tylko dodatkowy mechanizm który za każdym razem trzeba implementować samemu? Próbuję porządnie zabrać się za te wyjątki, ale mam jakiś niesmak konwertując błędy na wyjątki ![]() |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 4 655 Pomógł: 556 Dołączył: 17.03.2009 Skąd: Katowice Ostrzeżenie: (0%) ![]() ![]() |
"Standardowo" PDO rzuca wyjątkami z tego co pamiętam.
-------------------- Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP |
|
|
![]()
Post
#15
|
|
![]() Grupa: Zarejestrowani Postów: 2 885 Pomógł: 463 Dołączył: 3.10.2009 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Podobnie, jak cała biblioteka standardowa php. http://php.net/manual/en/language.exceptions.php
Ten post edytował darko 20.02.2011, 00:23:35 -------------------- Nie pomagam na pw, tylko forum.
|
|
|
![]()
Post
#16
|
|
Grupa: Zarejestrowani Postów: 260 Pomógł: 14 Dołączył: 8.09.2011 Ostrzeżenie: (0%) ![]() ![]() |
Tak, błąd przy wprowadzaniu danych od użytkownika nie jest sytułacją wyjątkową, więc wyjątki są nie na miejscu lepiej if'ować. Natomiast gdybyś nie mógł odczytać danych z katalogu (co zawsze powinno się udać) najlepiej zastosować wyjątki. Sama teoria niewiele Ci da, sam musisz zaczą pisać, to zrozumiesz kiedy używać wyjątków a kiedy if'ować Przepraszam ze odkopie temat ale jest to dla mnie kompletnie niezrozumialem i chcialbym sie dowiedziec dlaczego akurat tak. Dlaczego w sytuacji gdy wygodnie jest mi rzucic wyjatek gdy user wpisze błędne dane i zlapac go jeszcze w mojej klasie (zrobic specyficzna klasy błędów), zrobic sobie w swojej klasie bloki try catch dla roznych rodzajow moich błędów (i dodatkowo jesli kiedys mi sie zachce zmienic sposob reagowania na bledy to zmieniam to jedna linijka) mam robic ify i pisac 10x tyle kodu, i w razie zmiany reagowania na bledy wszystko lopatologicznie przepisywac. Dla mnie gdy user tworząc jakis event gdzie jest potrzebna do utworzenia data jego startu, i wpisze sobie tam aa-aaaa-aa zamiast daty to i tak mu nie utworze tego eventu wiec to jest bląd krytyczny ktory powinien przerwac normalny bieg programu i spowodowac wyswietlenie komunikatu co user wpisal nie tak. Crozin, styrałeś kolegę ze to niewygodne w obróbce bla bla bla. Co za problem dodac do klasy ImageException metode getErrorFilepath() i pole $filepath, a do konstruktora dodac dodatkowy parametr $filePath? A co jak komus sie zapomni przechwycic wyjątku i dopisac sensowny komunikat o bledzie do nazwy pliku? Jako uzytkownik wolalbym dostac z dwojga zlego komunikat "nie odnaleziono pliku" niz "C:\windows\plik.txt". -------------------- "The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time."
Tom Cargill, Bell Labs |
|
|
![]()
Post
#17
|
|
![]() Grupa: Zarejestrowani Postów: 2 885 Pomógł: 463 Dołączył: 3.10.2009 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
~Orzeszekk walidacja danych pochodzących od użytkownika to jest zwyczajna, normalna sytuacja, w której należy dane walidować i odpowiednio zareagować. Chodzi o to, że nie jest to nic nadzwyczajnego, z czym nawet przeciętnie napisana aplikacja nie mogłaby sobie poradzić, tym bardziej nie jest to sytuacja, której nie przewidział autor kodu. Tłumaczenie stosowania wyjątków i korzystanie z nich, gdzie popadnie, dla wygody, to nie jest - z wielu powodów - dobre podejście do tematu. Po pewnym czasie dojdziesz do sytuacji, w której atomowe operacje będą rzucały wyjątki, a kod aplikacji straci na czytelności. Wszystko to ma wpływ na późniejsze tzw. koszty konserwacji kodu.
-------------------- Nie pomagam na pw, tylko forum.
|
|
|
![]()
Post
#18
|
|
Grupa: Zarejestrowani Postów: 260 Pomógł: 14 Dołączył: 8.09.2011 Ostrzeżenie: (0%) ![]() ![]() |
![]() ![]() ![]() Chodzi o to ze np. gdy ktos wpisze stringa o dlugosci 300 w pole do 255 to moge tego stringa obciac i nie musze rzucac wyjątku , jednak z daty "reghbgfww" zadnej sensownej wartosci nie zrobie, wiec dalsze wykonanie programu jest bez sensu wiec czemu nie skorzystac z wyjątku. Tym bardziej ze mechanizm wyjątków pozwala na zrobienie wyjatkow o roznym stopniu "błędności" i rozroznianie ich między sobą, i mozna uzyc jednych klas wyjątków do oznaczania błędów - sytuacji wyjątkowych, a drugich - by uproscic sobie prace z walidatorem. idąc twoim tokiem rozumowania co twój, źle napisany SQL string to rowniez nie jest sytuacja wyjątkowa, a przypadek walidacji danych a jednak ASP.NET w momencie proby wykonania takiego czegos rzuca wyjątek. Nie wiem jak w php bo nie korzystam z PDO. Tak samo w niemal kazdym języku próba sparsowania tekstu na integer konczy sie rzuceniem wyjątku przez funkcje StrToInt, a czy to nie jest walidacja danych? -------------------- "The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time."
Tom Cargill, Bell Labs |
|
|
![]()
Post
#19
|
|
![]() Grupa: Zarejestrowani Postów: 2 885 Pomógł: 463 Dołączył: 3.10.2009 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
![]() ![]() ![]() Nie. To nie jest sytuacja wyjątkowa i nie ma tutaj potrzeby ręcznego sterowania aplikacją. Zawsze można zablokować pole i wystawić jakiś cieszący oko kalendarz do wybrania daty. Chodzi o to ze np. gdy ktos wpisze stringa o dlugosci 300 w pole do 255 to moge tego stringa obciac i nie musze rzucac wyjątku , jednak z daty "reghbgfww" zadnej sensownej wartosci nie zrobie, wiec dalsze wykonanie programu jest bez sensu wiec czemu nie skorzystac z wyjątku. jw. + zawsze możesz ustalić jakąś datę domyślną, to również nie jest sytuacja wyjątkowa. Tym bardziej ze mechanizm wyjątków pozwala na zrobienie wyjatkow o roznym stopniu "błędności" i rozroznianie ich między sobą, i mozna uzyc jednych klas wyjątków do oznaczania błędów - sytuacji wyjątkowych, a drugich - by uproscic sobie prace z walidatorem. Z pierwszą częścią zdania się zgodzę, z drugą już nie. Podstawowym problemem jest to, że nie rozumiesz zastosowania wyjątków. Wyjątki nie służą do "oznaczania błędów", a do nadzwyczajnego ręcznego sterowania aplikacją w wyjątkowych, nieoczekiwanych sytuacjach. idąc twoim tokiem rozumowania co twój, źle napisany SQL string to rowniez nie jest sytuacja wyjątkowa, a przypadek walidacji danych a jednak ASP.NET w momencie proby wykonania takiego czegos rzuca wyjątek. Nie wiem jak w php bo nie korzystam z PDO. Tak samo w niemal kazdym języku próba sparsowania tekstu na integer konczy sie rzuceniem wyjątku przez funkcje StrToInt, a czy to nie jest walidacja danych? Nie porównuj proszę C# z PHP. PDO obsługuje wyjątki. Każdy język zachowuje się nieco inaczej podczas konwersji zmiennych do określonego typu i nie ma to nic wspólnego z walidacją danych pochodzących od użytkownika. Znowu nie ma tutaj niczego nadzwyczajnego w takiej sytuacji, a rozwiązań pozornego problemu jest wiele, najprostsze z nich to konwersja zmiennej do oczekiwanego typu albo sprawdzenie typu jeszcze przed - jak to nazwałeś ładnie - sparsowaniem tekstu. Generalnie wyjątków powinno się używać wszędzie tam, gdzie faktycznie mogą pojawić się wyjątkowe sytuacje, które można obsłużyć, a następnie wznowić działanie aplikacji od instrukcji poprzedzających blok catch. W bardzo dużym uproszczeniu działa to w ten sposób, że do szczęścia nam czegoś tam brakuje, ale my, jako dobrzy programiści zostawiamy furtkę dla innych programistów korzystających z naszego kodu, zgłaszając im tylko tyle: "Hej! Tu czegoś brakuje! Coś tu nie gra." I zostawiamy im decyzję, co z tym faktem zrobią. Ogólnie ~Zyx bardzo ładnie to opisał kilka postów wyżej. -------------------- Nie pomagam na pw, tylko forum.
|
|
|
![]()
Post
#20
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
@darko: Błędne dane pochodzące z żądania HTTP są tak samo wyjątkowe jak błędny format danych z pliku (np. przy odczytywaniu obrazu PNG) czy format daty przy inicjalizacji obiektu klasy data. Wyjątki służą ogólnie do obsługi błędów, a nie jakieś bliżej nieokreślonej "sytuacji wyjątkowej" bo każdy błąd taką jest, każdy musi zostać przez kogoś przewidziany (inaczej program może działać w sposób nieokreślony). Wyjątki miały na celu przede wszystkim wyeliminować takie konstrukcje:
Na rzecz: Co miało na celu wymuszenie obsługi błędów, czego pierwszy przykład nie robi. W PHP sprawa jest jednak nieco skopana bo obsługa wyjątków nie jest wymuszona na poziomie języka / składni, przez co drugi wariant również tej gwarancji nie daje. |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 18.07.2025 - 08:40 |