Kurs: PHP programiranje Materijali vezani uz ovu lekciju: - Test rukovanje greškama - Rukovanje greškama (PDF dokument) Rukovanje greškama veoma je bitan element u svakom programskom jeziku, na praktično svim platformama. Nikada ne možemo biti potpuno sigurni, šta će i kada korisnik uraditi, kao ni kada će sistem i njegovi resursi, iz nekog razloga, omesti naš program u pravilnom izvršavanju. Upravo iz tog razloga, obaveza programera je da predvidi koje tačke u programu predstavljaju potencijalnu opasnost po njegovo izvršavanje i da te pozicije obezbedi dodatnim zaštitnim sistemima. Najbolnije tačke jedne aplikacije su trenutci kada se ta aplikacija obraća resursima. A ti resursi, odnosno, njihovo poreklo, najčešće je baza podataka ili fajl sistem. Pored njih, kritični trenutci događaju se i prilikom svakog korisničkog ulaza u aplikaciju (unos podataka), zatim striminga, kominikacije sa uređajima... Osnovno rukovanje greškama je dosta jednostavno. Treba samo ispoštovati sledeći set pravila:
To možemo uraditi ručno ili putem try catch blokova, u zavisnosti od tipa greške koji očekujemo i toga da li je u stanju da bude obrađena kao izuzetak. Ručna obrada grešaka na najnižem nivouPre nego što pristupimo nekom resursu, najbolje je ispitati da li taj resurs postoji i na osnovu toga nastaviti delovanje programa. Na primer:<?php Ova funkcija trenutno prekida izvršenje programa uz emitovanje (ili bez njega) korisnički definisane poruke. Ukoliko naime, dalje izvršenje programa zavisi od resursa koje treba da pročitamo (na primer od fajla mojFajl.txt u prethodnim primerima), onda svakako treba prekinuti dalje izvršavanje programa, ukoliko tog resursa nema. U ovom primeru, ukoliko fajla nema, biće ispisana poruka greške, zatim poruka funkcije die (kraj) i izvršavanje će biti prekinuto. <?php Ručno emitovanje grešakaU prethodnom primeru, prekidali smo izvršavanje programa funkcijom die(). Takođe, moguće je i emitovanje sopstvene poruke o grešci bez prekidanja izvršavanja. Ova linija koda će na poziciji na kojoj se nalazi, emitovati poruku o grešci.trigger_error("Moja greška"); Tip na ovaj način emitovane greške će biti 1024 (Notice), što možda nije nivo ozbiljnosti koji želimo da predočimo korisniku. Da bismo ovo promenili, možemo eksplicitno, kao drugi parametar, uneti jedan od tri tipa grešaka koje ova funkcija prihvata i čije konvencije bi trebalo da poštujemo pri korišćenju:
Na primer: trigger_error("Moja greška", E_USER_WARNING); Ručno rukovanje greškamaPored sopstvene aktivacije poruke o grešci, možemo napraviti i funkciju koja će presresti grešku i biti izvršena umesto ugrađene funkcije za rukovanje greškama, odnosno, sopstevni rukovalac greškama.Ovakva funkcija prihvata parametre, broj greške, poruku greške, fajl koji je izazvao grešku, liniju greške, dump (niz varijabli i njihovih vrednosti aktivnih u trenutku greške). Ovi parametri su opcioni, ali njihov redosled treba poštovati pri izgradnji funkcije. function mojHendler($brojGreske, $porukaGreske) Nakon što napravimo funkciju koja želimo da rukuje greškama, potrebno je da je inicijalizujemo kao podrazumevani rukovalac greškama: set_error_handler("mojHendler"); Nakon toga, sve greške, će biti, umesto u ugrađeni rukovalac, prosleđivane u našu ručno kreiranu funkciju. Lista kodova (brojeva) greške, u odnosu na funkciju trigger_error, ovde je malo proširena i sastoji se od 7 kodova:
Greške iz ove liste, možemo priključiti čak i samom hendleru, kroz parametar funkcije set_error_handler: set_error_handler("mojHendler", E_USER_NOTICE); U ovom slučaju, kroz naš hendler, proći će samo greške tipa E_USER_NOTICE, dok će ostale greške biti obrađivane kroz ugrađeni hendler Evo jednog primera kompletnog koda: <?php Nakon uhvaćene greške, najbolje je proslediti je u neki log u bazi ili na fajl sistemu. Loger za neki specifičan sistem (na primer, da pamtimo logove u bazi) možemo napisati ručno, dok za standardne tipova log-a možemo koristiti i ugrađenu funkciju error_log(). Ova funkcija prima do četiri parametra: poruku greške, tip logovanja, destinaciju i zaglavlje. Poruka greške je bilo koja korisnička poruka, za koju želimo da bude zapamćena u logu. Tip logovanja predstavlja, zapravo, destinaciju slanja ovog log-a, pri čemu je:
<?php Rukovanje izuzecimaNije uvek moguće rešavanje problema sa resursima (i sličnih) putem uslovnih izvršavanja koda. Ponekad je jednostavno, potrebno, pokušati nešto da bi se znalo da li to nešto može da se uradi. U tom slučaju, treba nam mehanizam koji će reagovati tek nakon dolaska do greške, a da pri tom ne poremeti normalan rad programa. Ovakav mehanizam postoji i naziva se rukovalac izuzecima.Rukovalac izuzecima je pojam blisko vezan za objektno orjentisano programiranje, jer u stvari, izuzatak jeste nešto što je karakteristično za određeni događaj određene klase. Vratimo se na primer sa početka lekcije, gde smo pokušali da pročitamo nepostojeći fajl: <?php ... gde smo problem nepostojećeg fajla rešili tako što smo postavili uslov ispred čitanja: if(file_exists("mojFajl.txt")) Recimo da je sve ovo sada deo jedne klase koja rukuje fajlovima. <?php Poziv funkcije citaj() ove klase, neće prikazati grešku, što je očekivano. Takođe, mogli smo i ubaciti logiku, koja bi izbacila poruku o nepostojanju fajla. Ali, da bi naša greška o nepostojećem fajlu, bila u konvenciji izuzetaka, odnosno, da bi korisnici klase (ukoliko je izuzetak izbačen iz klase) ili mi sami mogli da je „uhvate” kao standardan izuzetak, standardnim metodama za hvatanje izuzetaka, potrebno je da i objekat koji emitujemo prilikom obrade ove naše greške, bude tipa izuzetak. <?php Ovako emitovanu grešku (izuzetak), lako hvatamo upotrebom try-catch bloka. Potrebno je samo da naznačimo u kom delu predviđamo događanje izuzetka (u ovom slučaju to je poziv metode citaj()) i stavimo ga u try blok, a zatim dodamo alternativni kod (koji treba da se izvrši ako try blok ne uspe) u catch blok. Catch blok prihvata parametar tipa Exception, koji sadrži propertije i metode za razotkrivanje određenih detalja vezanih za sam Exception. try Umesto new Exception, koji smo „izbacili” iz funkcije citaj(), mogli smo da izbacimo i instancu sopstvene klase izuzetaka. Naravno, ukoliko smo je prethodno napravili; a možemo je napraviti nasleđivanjem klase Exception i dodavanjem svojih elemenata: class mojIzuzetak extends Exception Najvažnije iz lekcije
|