kfisker Mester
07. januar 2013 - 13:34 Der er 27 kommentarer og
1 løsning

Fejlhåndtering ved standard mysql contra PDO

Jeg har arbejdet med PDO i en periode, men fejlhåndteringen piner mig en smule.

Jeg har denne standard mysql-forespørgsel:

$sql_query = ("
  SELECT time_stamp, count_day
  FROM statistik
  ORDER BY time_stamp ASC;
");

$query_stat = mysql_query($sql_query) or die (error_handler(mysql_error()));

Forsøger jeg at hente data fra en tabel eller en kolonne der ikke eksisterer vil min error_handler-funktion blive aktiveret og jeg kan her logge fejlen.

Jeg har denne PDO forespørgsel:

try { 
    $stsm = $conn->prepare("SELECT time_stamp, count_day FROM statistik ORDER BY time_stamp ASC");


catch(PDOException $pdo_error) {
    die (error_handler($pdo_error));
}

try { 
    $stsm->execute();


catch(PDOException $pdo_error) {
    die (error_handler($pdo_error));
}


Med denne fanger jeg fejl i min forespørgsel eller i min execute. Jeg synes bare det er voldsom meget ekstra kode.

Er det måden at gøre det på, eller kan det gøres smartere?
olebole Nybegynder
07. januar 2013 - 14:06 #1
<ole>

Det ser ganske småt og smart ud  =)

/mvh
</bole>
kfisker Mester
07. januar 2013 - 14:22 #2
olebole...> Det kan jeg kun tolke som at det ikke umiddelbart gøres smartere?
olebole Nybegynder
07. januar 2013 - 14:31 #3
Det er i hvertfald måden, jeg selv håndterer fejl i forbindelse med PDO  =)
kfisker Mester
07. januar 2013 - 14:45 #4
Okay, jamen så burde det jo ikke være helt af vejen ;)

Du samler som sædvanlig ikke på point?
erikjacobsen Seniormester
07. januar 2013 - 15:13 #5
Du kan

try { 
    $stsm = $conn->prepare("SELECT time_stamp, count_day FROM statistik ORDER BY time_stamp ASC");
    $stsm->execute();

catch(PDOException $pdo_error) {
    die (error_handler($pdo_error));
}
olebole Nybegynder
07. januar 2013 - 15:31 #6
@Erik: Det kan man sagtens. Hvis der er fejl i begge udtryk, får man dog kun udskrevet den første
erikjacobsen Seniormester
07. januar 2013 - 15:38 #7
I dette tilfælde giver det ikke mening at prøve nummer 2, hvis den første fejler. Li'som en fraskilt mand, der ikke prøver det projekt een gang til ;)
arne_v Ekspert
07. januar 2013 - 15:41 #8
Derudover er det jo heller ikke anderledes end i #0.
olebole Nybegynder
07. januar 2013 - 15:43 #9
Du ved godt, at videnskabelig metode bygger på, at gentagelser af samme forsøg, skal give samme resultat ... skrev manden med 'eks i anden'  *D
olebole Nybegynder
07. januar 2013 - 15:45 #10
#9 var en kommentar til Eriks #7  *o)
michael_stim Forsker
07. januar 2013 - 15:45 #11
#8
Udover at man "sparer" en try/catch.
olebole Nybegynder
07. januar 2013 - 15:53 #12
#11: Jeg tror, Arne hentydede til, at spørgers konstruktion jo også kun udskriver første fejl. Derfor var min kommentar #6 noget vrøvl  *o)
michael_stim Forsker
07. januar 2013 - 15:57 #13
OK, så vågnede jeg også ;o)
olebole Nybegynder
07. januar 2013 - 16:03 #14
- og skulle der være opstået tvivl i forbindelse med lidt inforståede kommentarer, så er der koncensus om, at Eriks forslag i #5 gør det samme som spørgers eget script - nøjagtig ligeså godt  =)
erikjacobsen Seniormester
07. januar 2013 - 16:11 #15
#XIV: Men det er så anvendelsen af die(...) i catch-delen, der gør det. Ellers må man sige at anvendelsen af 2 try/catch giver god mening, hvis nummer 2 kan udføres, selv om nummer 1 fejler. Ellers bør man for læselighedens skyld anvende een try/catch.
arne_v Ekspert
07. januar 2013 - 19:22 #16
Enhver afbrydelse af flow vil have den effekt - die, return, throw.

Og jeg vil tro at det er ret tit for database operationer at man vil afbryde ved foerste fejl.
arne_v Ekspert
07. januar 2013 - 19:23 #17
Saa ioevrigt lige at PHP 5.5 skulle faa finally.

Det vil nok goere en enkelt try catch finally endnu mere attraktiv da man kan sample hele cleanup for baade fejl og success et enkelt sted.
kfisker Mester
09. januar 2013 - 13:23 #18
Nedenfor ses mit test-script.

Jeg kan godt bruge noget sparring på nedenstående spørgsmål:
Skal jeg ændre errormode til silent i produktion, eller vil nedenstående script fange fejlene, og dermed ikke udgøre en risiko?

Er "if ($stsm->errorCode() == 0)" overflødig og burde udelades?

Er der noget der springer i øjnenen i nedenstående, eller noget jeg måske burde medtage?

De steder jeg bruger echo i forbindelse med fejl vil blive håndteret af en error-funktion.


<?php
$db_host = "xxx";
$db_name = "xxx";
$db_user = "xxx";
$db_pass = "xxx";

try { 
    // database connection 
    $conn = new PDO("mysql:host=".$db_host.";dbname=".$db_name.";charset=utf8", $db_user, $db_pass, array(PDO::ATTR_PERSISTENT => true));



catch(PDOException $pdo_error) {
    echo "Fejl i databaseforbindelsen";
    exit;
}

$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = ("
    SELECT *
    FROM `admins`
    WHERE `user` = :user
");

$sql_param = array(
    'user' => "fornavn\efternavn"
);

try { 
    $stsm = $conn->prepare($sql);


catch(PDOException $pdo_error) {
    echo "Fejl i prepare.";
    exit;
}

try { 
    $stsm->execute($sql_param);


catch(PDOException $pdo_error) {
    echo "Fejl i execute";
    exit;
}

if ($stsm->errorCode() == 0) {
    if ($stsm->rowCount() > 0) {
        while ($row_user = $stsm->fetch()) {
            echo $row_user['USER']."<br>";
        }
    } else {
        echo "Ingen rækker";
    }
} else {
    $errors = $stsm->errorInfo();
    echo($errors[2]);
}
?>
erikjacobsen Seniormester
09. januar 2013 - 14:07 #19
Du flytter bare din if-while ind i try.

Det vil altid være godt, at være sikker på at slutbrugeren ikke ser tekniske fejlbeskeder, men at support/udvikler gør.
kfisker Mester
09. januar 2013 - 14:15 #20
erik...> Ikke forstået?

Mit test-script kan jeg ikke få til at genere andre fejl end dem jeg selv echo'er.

Jeg kan ikke generere en fejl der får $stsm->errorcode til at vise en fejl.

Ændrer jeg f.eks. i tabelnavnet dør den i prepare. Laver jeg en fejl i $sql_param dør den i execute.

Den sidste fejlmulighed kan jeg ikke trigger, derfor jeg spørger om den er overflødig?

Mine try+catch vil blive lagt en funktion, således de ikke skal optræde overalt i mine scripts. Den del har jeg allerede fået til at virke. Tester bare i mit test-script, da det er mere overskueligt.
arne_v Ekspert
09. januar 2013 - 17:42 #21
Jeg tror at jeg ville bruge en enkelt try catch fremfor mange. Hvad fejlen er boer fremgaa af selve exception.
arne_v Ekspert
09. januar 2013 - 17:44 #22
Men du boer hive al information ud fra exception.

Der er mange gode felter i den klasse!

http://php.net/manual/en/class.pdoexception.php
arne_v Ekspert
09. januar 2013 - 17:47 #23
Med hensyn til hvad der skal goeres saa vil jeg sige:

demo kode:

echo og exit (eller die) er helt fin

rigtig kode:

du logger al information og saa smider du en ny exception som catches i dit presentation layer og giver brugeren en passende besked uden tekniske detaljer
kfisker Mester
09. januar 2013 - 19:50 #24
Så har jeg vist efterhånden fået svar på mine usikkerheder.

Det eneste jeg ikke synes at have fået svar på er hvorvidt dette er dobbeltkonfekt:
if ($stsm->errorCode() == 0) {
}
arne_v Ekspert
09. januar 2013 - 22:19 #25
Laes:

http://php.net/manual/en/pdo.error-handling.php

som viser hvordan du kan skifte mellem exceptions og error code.

PS: Jeg tror at success er '00000' ikke 0
kfisker Mester
10. januar 2013 - 08:02 #26
Tak for linket.

Det afklarede i hvertfald mit sidste spørgsmål.

Tak til alle for bidrag.

Hvis der er nogen der vil have point, er det nu der skal lægges et svar :)
erikjacobsen Seniormester
10. januar 2013 - 13:41 #27
"Mit test-script kan jeg ikke få til at genere andre fejl end dem jeg selv echo'er"

Der er flere fejl, der kan opstå, selv om du ikke lige kan frembringe dem selv. Fx at forbindelsen til databasen forsvinder mellem din connect og din query.
arne_v Ekspert
10. januar 2013 - 13:47 #28
svar for mine bidrag i den sidste trediedel af traaden
Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links

Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester





Computerworld
Jens Højgaard skrev negativ anmeldelse på Trustpilot - nu er han blevet sagsøgt for 11.419 kroner
En negativ anmeldelse på Trustpilot om et inkassofirma har indtil videre kostet den selvstændige hvidevare-reparatør Jens Høgni Højgaard flere tusinde kroner og en tur i retten. Forklaringen er, at inkassofirmaet har forbudt kunder at udtale sig negativt i offentlighed om selskabet.
CIO
Lille it-virksomhed med 18 ansatte: "Sådan vinder vi de offentlige udbudsopgaver"
Hvis man er lille og vågen, kan man sagtens hugge de udbudsopgaver, der tidligere gik til de store firmaer. På et enkelt år er der næsten sket en fordobling i antallet af virksomheder under 20 personer, som vinder udbudsopgaver. Her kan du møde en af dem.
Comon
Så nemt installerer du en "ren" Windows 10 uden crapware
De fleste nye computere kommer med præ-installerede programmer, der kan gøre din computer langsom. Læs her, hvordan du let installerer Windows 10 uden crapware.
Channelworld
Overblik: Det ved vi efter første retsmøde i den store Atea-bestikkelsessag
Den første sag om bestikkelse af offentlige ansatte kører i disse dage, hvor offentlige ansatte anklages for at have modtaget bestikkelse fra it-giganten Atea.
White paper
Invester i nye it-systemer og øg din konkurrencefordel
Sådan øger du antallet af kunder uden at øge bemandingen, få mindre stress i hverdagen og et langt bedre forhold til kunderne end tidligere.