$query = "select * from tabulka"; // pouzivam zvlast $query, protoze kdyz debuguju, tak potom pred to pridam echo a vidim jak se dotaz poskaldal if($result = mysql_query($query)) { while(mysql..... to znate } else { trigger_error("Nanstala chyba :v případě ladění bude konstanta DEBUG nastavena na true v ostrem provozu na false v kazdem pripade by se chyby mely logovat.
".mysql_error()."
". $query, E_USERERROR); }; // Zároveň by mělo být ošetřeny chyby standartním způsobem. set_error_handler('catch_error'); function catch_error(...) { if (DEBUG) { echo $error_msg; } else { echo 'Doslo k chybe, zkuste to pozdeji ...'; log_error($error_msg); }; };
Opet dalsi clanek, ktery mi prijde uplne "mimo misu".
Dnešní PHP okénko popisuje různé způsoby ošetření chyb a rozebírá jejich vhodnost v různých situacích. - Ale vzdyt tu byl rozebran akorat jediny zpusob, a to osetreni podminkou. Vyjimky jsou urcite mechanizmus, jak osetrovat chyby. Rict, ze vyjimky nejsou vetsinou nejvhodnejsi reseni, je jen odbyti. Minimalne by bylo dobre ukazat, jak funguji. Prvni priklad se da osetrit napriklad prave tim, ze vyhodite vyjimku a podle toho ji pak zpracujete. Ale treba o nekolik urovni vyse.
Opravdu nevim, co prijde autorovi neprehledne na druhem reseni v prvni priklade. Rekl bych, ze je to standardni zpusob, jak osetrit chyby. Ja osobne mam radeji kratsi zpusob:
if (!mysql_query("SELECT * FROM tabulka")) { echo "Chyba v SQL dotazu!\n"; }Casem si stejne programator casto vytvori nejakou vlastni "komponentu" pro pristup k db, nebo zacne pouzivat nekterou dostupnou.
Pouzivat mysql.trace_mode povazuji jen za jakousi berlicku. Stejne je vetsinou potreba nejak zpracovat chybu pri dotazu.
Já jsem narazil na několik problémů, s errory si hraju už dost dlouho a tak jsem vymyslel tohle...
<?php /** * Nějaká třída */ class Foo{ /** * Konstruktor, zvláštní tím, že nevrací hodnotu. * @param string */ function Foo($arg){ if(!is_scalar($arg)){ $this = & new Error('...'); return; } } /** * Normální metoda. * @param string */ function doSomething($arg){ if(!is_scalar($arg)){ return new Error('...'); } } } $foo = & new Foo(array('test')); if(isError($foo)){ # Poslat výš, nebo tak něco... } $res = $foo->doSomething(array('bububu')); if(isError($res)){ # Poslat výš, nebo tak něco... } ?>
Tohle je sice funkční, ale sémanticky zatraceně blbá metoda. Předefinovat this je hodno blbce jako já .-). A navíc to nefunguje v PHP/5. Omlouvám se za délku příspěvku, jdu ukázat další, pěknější metodu...
<?php /** * Nějaká třída */ class Foo{ /** * Konstruktor, zvláštní tím, že nevrací hodnotu. * * @param string * Chybová proměnná. * @param string */ function Foo(&$e, $arg){ if($e) return; if(!is_scalar($arg)){ $e .= __FILE__ . '->Foo(): Expected string, ' . gettype($arg) . ' passed.'; return; } } /** * Normální metoda. * @param string * Chybová proměnná. * @param string */ function doSomething(&$e, $arg){ if($e) return; if(!is_scalar($arg)){ $e .= __FILE__ . '->doSomething(): Expected string, ' . gettype($arg) . ' passed.'; return; } } } $e = ''; $foo = & new Foo($e, array('test')); $res = $foo->doSomething($e, array('bububu')); if($e){ die($e); } ?>
Tahle metoda je poměrně spolehlivá. Má také své mouchy. Dá se poměrně slušně vylepšit stopováním pomocí debug_backtrace(). Co se týče odchytu PHP chyb, doporučuji definovat pomocí php funkce set_error_handler() nastavit vlastní funkci na výpis chyb a ty v ostrém provozu raději logovat, než posílat na klienta.
Ještě jednou se omlouvám za délku příspěvku. Jo a mimochodem, autor nepíše tak mizerně, rozhodně ne pro úplné začátečníky...
PS: Rád kdykoliv poradím... stačí napsat; mordae@mordae.net
Cílem PHP okénka je "přinášet drobné postřehy z programování v PHP, vždy pokud možno s uvedením konkrétních ukázek kódu" (perex prvního dílu). Toto okénko přináší tři postřehy:
Se všemi třemi chybami se poměrně často setkávám, proto jsem považoval za užitečné je popsat. Nehledejte za tím nic víc. Jistě by se toho dalo o kontrole chyb napsat víc, zmínit např. set_error_handler a trigger_error, ale nebylo to záměrem článku.
Mrzí mě, že hned pět diskutujících (PD., Lukoko, Michaels, efesak, cpt_nemo) si v článku nevšimlo myšlenky, že ošetřovat chyby přímo v kódu není ve většině případů ten nejlepší způsob. Když se kód pro ošetření standardních chyb umístí do zvláštní funkce, jednak se tím zdroják zpřehlední a jednak získáme možnost ošetřovací kód měnit podle potřeby. Všechny zmíněné způsoby jsou jen variantou toho samého nešikovného přístupu:
<?php if (!mysql_query("SELECT * FROM tabulka")) { echo "Chyba v SQL dotazu!\n"; } $RS = @mysql_query($SQLText) or die("Chyba SQL dotazu"); ?>
Ošetření chyb mimo hlavní kód kromě už zmíněných výhod dává možnost zpracování chyb v závislosti na prostředí:
<?php function mysql_q($query, $ignored = array()) { $result = mysql_query($query); if (!$result && !in_array(mysql_errno(), $ignored)) { if (DEBUG) { echo "Error in $query: " . mysql_error() . "\n"; } else { // poslání mailem, zápis do logu, ... } } return $result; } ?>
Podobný přístup je i využití direktivy mysql.trace_mode, která z SQL chyb vytvoří standardní PHP chyby, které můžeme ošetřovat stejným způsobem jako normální PHP chyby (v testovacím prostředí vypisovat, v provozním ukládat do logu).
Ad mysql.trace_mode - to proste neni reseni. Co kdyz se zmeni databaze, ke ktere pristupuji, z mysql treba na IB/FB? Pak je mi to zcela nahouby. Prijde mi to navic jako spatny programatorsky postup - ta chyba neni v php kodu, stala na uplne jinem bezicim serveru a podle toho by mela byt take zpracovana.
"Zkusenejsi" programator stejne bude pristupovat k databazi nejak takto:
if (!$db->query("SELECT ...") { // osetreni chyb... }a pak neni problem mit logovani chyb zapouzdrene v pouzitem objektu. Protoze vsak osetreni neznamena vzdy jen zalogovani chyby, ale treba provedeni nejakych dalsich akci, tak podobnemu ifu se proste casto nevyhnete. Asi byste nechtel psat pro nekolik moznych chybu zvlast osetrujici funkci. Navic jak sam v clanku pisete: pokud se ale ošetření kritické chyby liší podle kontextu, je asi nejlepší ho přeci jen dát přímo do kódu.
Tento clanek proste neni vubec v nicem prinosny. O osetrovani chyb v php neni receno skoro nic. Vyjimky jste zcela odsoudil, pritom prave ty spise jsou nastroj pro ošetření chyb mimo hlavní kód. Neni zmineno, zda a jak lze napsat vlastni error handler definovany uzivatelem, funkce trigger_error() a podobne veci, tykajici se opravdu osetrovani chyb.
Clanek vicemene jen o if (mail odesel) {ok} else {chyba}
patri spise k clankum o podminkach a cyklech pro uplne zacatecniky. Nikoli k clankum o overovani chyb.