Názory k článku PHP okénko: Kontrola chyb

  • Článek je starý, nové názory již nelze přidávat.
  • 25. 4. 2005 8:29

    PD. (neregistrovaný)
    $result = MySQL_query(dotaz);
    if ($result === false) Error(1);

    a v souboru nacitanem pro vsechny skripty mit definovanou funkci Error.
    Pripadne misto toho dat kod chyby do promenne a require('error.php').

    IMHO to spojuje vyhody nereseni (citelny kod) s resenim (chyby jsou osetreny)
  • 25. 4. 2005 10:20

    Lukoko (neregistrovaný)
    Jednou sem mi stalo, ze sem mel vypnuty error reporting a pak sem nemoch prijit, na to, jaktoze to nefunguje: $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 { echo "Nanstala chyba :
    ".mysql_error()."
    ". $query; } Timhle zpusobem zarucene pridete na to, coje spatne
  • 25. 4. 2005 10:25

    Lukoko (neregistrovaný)
    // znova se zalamovani radku
    Jednou sem mi stalo, ze sem mel vypnuty error reporting a pak sem nemoch prijit, na to, jaktoze to nefunguje:

    $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 {
    echo "Nanstala chyba : <br />".mysql_error()."<br /> ". $query;
    }

    Timhle zpusobem zarucene pridete na to, coje spatne
  • 25. 4. 2005 13:35

    Vít Peprníček (neregistrovaný)
    No nevím jestli je rozumné uživateli zobrazovat dotazy a pomahat tak hacknout web. Doporucil bych spise tento zpusob
    $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 : 
    ".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); }; };
    v případě ladění bude konstanta DEBUG nastavena na true v ostrem provozu na false v kazdem pripade by se chyby mely logovat.
  • 25. 4. 2005 10:45

    Pachollini (neregistrovaný)
    Vždy't v tom článku nakonec o kontrole chyb nic není! Způsob 1 není dobrý, způsob 2 už vůbec ne, způsob 3 také moc ne, takže možná 1? Je tohle myšlené vážně?
  • 25. 4. 2005 11:07

    jirka (neregistrovaný)
    koukam ze zase kvantita drtive porazi kvalitu, tenhle clanek zacinajicim programatorum v php spis skodi nez pomaha - v podstate se zde dozvime, ze osetrovat chyby se ma, ale tezko rict jak? co treba zminit se o error handleru? navic zavrhnout mechanismus vyjimek jednou vetou je take unikatni. pochybuju ze nekdo se zdravym rozumem jeste pouziva primo mysql_* (a podobne) funkce - od toho je tu prece zapouzdreni, jako je AdoDB, Creole, Pear::DB apod., ktere pri chybe vyvolaji vyjimku a neni pak problem vse osetrit. autor tehle clanku by tohle mel vedet a ne byt v ucebnici o lekci dal nez o cem pise.
  • 25. 4. 2005 12:40

    Jan Tichý (neregistrovaný)
    To je zase jeden clanek o nicem...

    Jinak s tim vyhazovanim Exceptions u normalnich PHP funkci, neni zase az takovy problem nadefinovat si jednoduse vlastni error handler (http://cz.php.net/manual/en/function.set-error-handler.php), ktery tu vyjimku pri normalni chybe vyvola...
  • 25. 4. 2005 13:02

    Michaels (neregistrovaný)

    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.

  • 25. 4. 2005 15:21

    martin (neregistrovaný)
    to jste si ještě nevšiml, že celý tento PHP seriál je absolutně o ničem? Stačí se podívat na autorův blog a bude vám vše jasné.

    Autor je nedouk, který ustrnul jako pokročilý začátečník, bohužel má ale snahu odborně poučovat ostatní. Znáte to - "kdo neumí, učí". Kdyby aspoň ty svoje snahy podal nějak rozumně, aby se s tím dalo v diskusi polemizovat. Bohužel ale s tímto a předchozími články polemizovat nijak nejde. Neobsahují totiž nic.
  • 25. 4. 2005 15:48

    Mordae (neregistrovaný)

    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

  • 25. 4. 2005 16:13

    efesak (neregistrovaný)
    a co treba @$result = mysql_query($query) or chyba(); je to na jednu radku, a je to i docela pochopitelny... function chyba(){ echo "Nastala chyba: ".MySQL_ErrNo(); echo "
    \n"; echo "Popis chyby: ".MySQL_Error(); }
  • 25. 4. 2005 16:14

    efesak (neregistrovaný)
    function chyba(){
    echo "<b>Nastala chyba:</b> ".MySQL_ErrNo();
    echo "<br />\n";
    echo "<b>Popis chyby:</b> ".MySQL_Error();
    }

    @$result = mysql_query($query) or chyba();

    tohle mi pride jednodusi
  • 25. 4. 2005 16:32

    cpt_nemo (neregistrovaný)
    Tak tenhle posledni dil me donutil se zaregistrovat. Dyt cela ta serie je uplne, ale uplne k nicemu. I zacatecnikovi je to k ... Spousta kecu o nicem misto napsani (zjednodusene): $RS = @mysql_query($SQLText) or die("Chyba SQL dotazu");

    Misto die nejaka vlastni err fce, redirekt na chybovou page apod. ....

    A je z toho clanek o par vetach ... A zase je to jenom o kontrole chyb vuci DB, kde jsou kontroly chyb vstupu napr. z formularu?
  • 26. 4. 2005 10:49

    Jakub Vrána

    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:

    1. Ne všechny chyby je vhodné ošetřovat přímo v kódu a často je lepší vytvořit si na to funkci nebo použít jiný mechanismus.
    2. Některé chyby je naopak nutné ošetřovat vždy, vzhledem k jejich specifičnosti klidně přímo v kódu.
    3. Na produkčních serverech je záhodno vypnout zobrazování chybových hlášek, místo toho je lepší je logovat.

    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.

  • 25. 4. 2005 23:44

    mintaka (neregistrovaný)
    I když ten článek je jen takový malý štěk, možná pomůže zájemci o problematiku kontrolu chyb alepoň tahle diskuze.

    A tak přihodím pár drobků na hromádku.

    Pokud jde o větší projekt a nezáleží příliš na maximálně rychlém kódu, je podle mě vhodné vytvořit si něco jako "log report".

    Definuji jednu proměnnou - LogLevel a v programu pak používám podmínky typu

    if (LogLevel>3) echo "Program se snaží dělat to a to.";

    Takže na jednom místě si můžu určit, co všechno mi bude program vypisovat. Pokud chci ladit jen určitou část, tak LogLevel pro určitý úsek zvětším.

    Kdybyste se po dokončení projektu přeci jen chtěli logovaní zbavit a logovaní je vždy na jednom řádku, stačí nějakým automatem projet scriptíky a smazat všechny řádky na kterých se vyskytuje slovo LogLevel. V případě víceřádkového logování lze použít komentář před a po logu, kerým logovací část přesně vymezíte a třebas přes regulární řetězce se jí pak zbavíte.

    Jinak podobný mechanismus je použit ve spoustě programů. Třeba v SAMBE.
  • 26. 4. 2005 7:46

    Jakub Vrána

    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).

  • 26. 4. 2005 11:12

    Martin Mayer (neregistrovaný)

    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.

  • 26. 4. 2005 8:58

    Frn (neregistrovaný)
    Nerad bych se redaktorů dotknul, ale prošel tenhle článek (resp. jeho nadpis) korekturou ?

    A pokud ano, je vám známo, že anglický výraz "control" by se v použitém kontextu neměl překládat jako "kontrola chyb" ? V češtině je slova "kontrola" obvykle použito ve významu "ověřování" nebo "dohlížení". Jde tedy o "dohlížení na chyby" ? Aby se neflákaly a aby jich tam bylo co nejvíc ?
    Je mi z toho s prominutím na blití. Byl by opravdu tak velký problém článek nadepsat "ošetření chybových stavů" nebo aspoň "ošetření chyb" ???

    Za komančů se to v řeči hemžilo rusismy. Teď se čecháčkové otočili o 180 stupňu a zase pro změnu je to samý amerikanismus. Holt musíme být světoví za každou cenu. A nejhorší je, že se to objevuje přímo v článcích a ne v diskusi, kde by se podobné jazykové úlety daly očekávat.
  • 26. 4. 2005 12:07

    MaReK Olšavský
    Zlatý podporovatel
    Co treba pouzit PHP knihovnu, o ktere byl (dost dobry :-)) clanek u konkurence http://www.linuxsoft.cz/article.php?id_article=664 ? Umozni chyby nejen skryt, ale zaroven jsou v promenne (poli) kvuli moznoti reportovani dale, uschovani do souboru, ... Hlavne chyby nesmi jit na uzivatelskou cast webu, aby potencialnimu utocnikovi neukazaly strukturu databaze, pripadne jinak neumoznily zautocit... Zakladem jsou samozrejme kvalitne osetrene uzivatelske vstupy.
  • 12. 7. 2005 13:08

    Kamzik II (neregistrovaný)
    Nevim, jestli to nahodou nekdo nepsal uz prede mnou, ale daleko lepsi pro zacatecniky mi prijde konstrukce mysql_query(...) or die ("chyba, ktera se stala");

    Nejlepsi mi pak prijde reseni vyuzitim zpracovani vyjimek... Ale to si musi kazdy doprogramovat sam :-(
  • 3. 9. 2010 0:02

    Čecháček (neregistrovaný)

    Myslel, jsem že je to dílo amatéra. Článek je utnutý v půlce a nic neříká. Nejsem sám.