Kivételkezelés alkalmazása
Sziasztok!
Olvasgatok kivételkezelés témakörben és van pár fehér folt, ami csak nem akar kitisztulni a fejemben.
Adott ugye egy szituáció, amikor valami rosszul sülhet el, legyen mondjuk most ez egy szimpla fájlmegnyitás, majd beolvasás. Valamelyik sikertelen művelet esetünkben egy végzetes hiba, amikor emiatt le kell lőni az egész programot. Miért jobb az, ha try...catch-csel kapom el ezt az eseményt annál, minthogy egy feltételes szerkezettel vizsgálom, hogy sikerült-e a művelet vagy sem?
Ezt egy külföldi fórumon találtam és nagyjából leírja, hogy mi a problémám.Ha nincs file, akkor dob egy kivételt, eddig rendben is van. Utána viszont ugyanúgy megtehetné ugyanezt, de ehelyett try...catch-csel kezeli le, ha nem sikerül a beolvasás. Mi a különbség (a hasznosságát illetően) és miért jobb try...catch-elni annak ellenére, hogy sokkal jobban eszi az erőforrást, mint egy sima feltételvizsgálat?
Magyarul az nem tiszta, hogy miért jó nekem, hogy try...catch-csel fogom el a kivételeket, azonkívül, hogy ez utóbbi nem feltétlenül okoz fatal errort a programban?
(Ha hülyeségeket beszélek, akkor elnézést...:) )
■ Olvasgatok kivételkezelés témakörben és van pár fehér folt, ami csak nem akar kitisztulni a fejemben.
Adott ugye egy szituáció, amikor valami rosszul sülhet el, legyen mondjuk most ez egy szimpla fájlmegnyitás, majd beolvasás. Valamelyik sikertelen művelet esetünkben egy végzetes hiba, amikor emiatt le kell lőni az egész programot. Miért jobb az, ha try...catch-csel kapom el ezt az eseményt annál, minthogy egy feltételes szerkezettel vizsgálom, hogy sikerült-e a művelet vagy sem?
Ezt egy külföldi fórumon találtam és nagyjából leírja, hogy mi a problémám.
class FileOutputter
{
public function outputFile($file)
{
if (!file_exists($file))
return throw new Exception("File not found.",123);
try
{
$contents = file_get_contents($file);
}
catch (Exception $e)
{
return $e;
}
return $contents;
}
}
Magyarul az nem tiszta, hogy miért jó nekem, hogy try...catch-csel fogom el a kivételeket, azonkívül, hogy ez utóbbi nem feltétlenül okoz fatal errort a programban?
(Ha hülyeségeket beszélek, akkor elnézést...:) )
Hajjajj
return throw new Exception(...
ilyet se láttam még...Aztán a
file_get_contents
nem dob kivételt (illetve valahogy rá lehet venni a PHP-t, hogy a saját hibakezelője helyett inkább exceptionokat dobáljon), szóval a blokknak alapból nincs értelme. AztánException
-t nem ad vissza függvény (nem mintha bármi baj lenne vele szintaktikailag, de így értelmét veszti a kivételkezelés)A kivételdobálgatás azért jó dolog, mert nem kell adott esetben hibakódokat adogatni akár több szinten keresztül. Ebből következik, hogy helyben egyáltalán nem kötelező elkapni őket (akár a fél stacken is átugorhat, magyarán ott kell csak foglalkoznod a hibával, ahol logikailag kell). Másrészt sokkal beszédesebb is, mint egy hibakód (még ha el is van fedve valami
FILE_NOT_EXISTS
fantázianevű konstanssal). Egyszóval használjuk őket, mert hasznosak. Bár tényleg több erőforrást eszik, mint integereket egymásnak adogatni, nem valószínű, hogy ezen múlna az alkalmazás sebessége, maga a fájl beolvasása nagyságrendekkel lassabb lehet.Érdekes... :)
php { return throw new Exception("xx"); }
PHP Parse error: syntax error, unexpected T_THROW in php shell code on line 2
Kipróbáltam, mert mit lehet tudni... :-)
Szóval már szintaktikailag sem stimmel, de ha működne is, a kivételkezelés értelmét nem vesztené el: ha a return mögé egy függvényhívást teszel, ami Exception-t vált ki, akkor simán végigmegy a kivételkezelő mechanizmuson.
Egy gyanúm van: aki az eredeti kódot írta, csak véletlenül tette a throw-t a return mögé, ő egy Exception objektumot akart volna visszaadni. Ebből viszont az feltételezném, hogy a szerzője nem volt tisztában a kivételkezelés működésével.
Másik variáció, hogy a return a sajtóhiba és tudta, mit csinál (bár a további sorok ezt számomra kétségessé teszik, de nem kizárt, hogy én vagyok tudatlan)
Biztosan nem olyasvalakinek a
Link
stackoverflow
Azok közül is inkább a több pontot kapott változatok lehetnek érdekesek.
Csináltam egy gyors példát,
Nem teszteltem, lehet benne elírás...
Az egyik lényegét, amit már előttem is írtak, hogy a kivétel dobásától eltérő helyen tudod elkapni a hibaüzenetet. Az alábbiban, ha a fájl nem található, vagy nem olvasható az Framework class azt elkapja (a page renderelésénél lehetne bármi más hiba, db olvasás error vagy akármi) és a hibát formázva megjeleníti. Ez felhasználói élmény szempontjából jó, development környezetben az a jó ha megjelenik a hiba szövege, production környezetben már csak az a jó, ha egy dizájnos felület jelenik meg ahol értesítjük a usert, elnézést, hiba volt. Dolgozunk rajta.
Sokat lehetne még írni a kivételkezelésről, pl. nem csak hibák esetén érdemes exceptiont dobni, hanem pl egy form mezőinek validálása során exception-ökkel összegyüjthetőek a hibaüzenetek (bővebben: symfony 1.4 form validálás, validatorSchema).
Másik lényeges pont, lehet saját exception classt létrehozni, és a catch résznél megadni, hogy csak ezt a classt kapja el, így megoldva, hogy csak bizonyos kivételeket kezeljen le az adott programrész, másokat hagyjon tovább emelkedni vagy hogy mondjam, az action stack-ben.
Az Exception subclassok
Én mondjuk azt se hinném el bemondásra, hogy a kivételkezelést használó kód számottevően lassabb lesz.
Köszi, kipróbálom.
:D most nézem, utsó sort
$fw->renderer(1)