Foutafhandeling - Query - SQL

Door Jasper DS, 11 jaar geleden, 23.641x bekeken

Beste lezers,

omdat de meerderheid van de beginnende php-scripters niet goed weet hoe ze op een nette manier een query moeten afhandelen i.v.m. errors en foutmelding en dan maar kiezen voor de "or die()" methode die natuurlijk helemaal fout is heb ik een if/else structuur geschreven met de nodige commentaar.

Deze structuur kan je toepassen op (bijna) al je query's.

(bedankt Noppes en Santhe voor de sql-debbug functie!)

Gesponsorde koppelingen

Inhoudsopgave

  1. Algemene structuur
  2. Voorbeeld 1 - Het ophalen van gegevens
  3. Voorbeeld 2 - Invoeren van gegevens
  4. Samenvatting

 

Er zijn 39 reacties op 'Foutafhandeling query sql'

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Jordi Kroon
Jordi Kroon
11 jaar geleden
 
Goede tutorial!
alleen paar puntjes:
Let wel een beetje op je spelling.
En de meerderheid van de beginners weet niet eens wat MySQL injection is , Misschien dat je daar wat mee kan.
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
Ik zal dat nog toevoegen! ;)
The Force
The Force
11 jaar geleden
 
@Jordi: jij mag anders ook wel eens op je spelling letten, ik tel tien fouten in je bericht.

De tutorial is op zich goed, maar ik zie mij niet voor elke query zo'n stuk schrijven. Waar je uiteindelijk naar toe wilt is dat dubbele code voorkomen wordt. Je zou een klasse kunnen schrijven waar je een query aan een functie meegeeft. Eén functie voor als je een enkele rij terug wilt hebben en dergelijke. Natuurlijk bestaan die klassen allang en kan je ook een framework gebruiken die database-handelingen makkelijker voor je maken.

Edit: ik tel elf fouten.
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
@ The Force, dit is voor beginners zodat ze de 'or die' manier niet meer gebruiken. Ik denk dat de stap naar dit stukje code minder groot is dan naar een klasse.
Wouter J
Wouter J
11 jaar geleden
 
1 +1 -0 -1
Goede tutorial. Alleen voor beginners zou ik er nog wat dingen bij doen:

- Ik zou niet een script plaatsen en dan met comments aangeven wat er gebeurd. Ik zou elke regel/ 2 regels apart nemen en uitleggen wat er gebeurt.
- Misschien ook handig om aan te geven dat iedereen op php.net kan zien wat een functie returned? Ik ontdenk namelijk vaak dat beginners dat niet weten. (Wellicht maak ik wel eens een tut over php.net)
- mysql_query() geeft niet altijd true terug, bij SELECT, SHOW, DESCRIBE, EXPLAIN geeft hij een result terug die je moet fetchen.
- foutafhandeling doe je niet alleen bij een query. Ook bij connecten en select db.
- Je gebruikt nu === false. Het is handig om ook aan te geven dan !$var ook werkt en de verkorte manier is.
- SanThe -
- SanThe -
11 jaar geleden
 
0 +1 -0 -1
Ik dacht dat je het geheel zou aanpassen aan het topic.
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
Ja, ik ga jouw functie er in zetten.
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
@ wouter, ik heb al een deel van jouw puntjes proberen te wijzigen.

@ Santhe, jouw verbeterde functie staat erin
- Mark -
- Mark -
11 jaar geleden
 
0 +1 -0 -1
Waarom zit de echo in de functie gebakken?

Je gaat er nu vanuit dat het php blok tussen de body tags zit. Dat is dus vaak niet het geval. Je kunt er beter return van maken. Als het php blok tussen de body tags staat kun je de functie aanroepen met echo als dat gewenst is. Als het php blok boven de html staat kun je alle fouten ergens anders in opslaan ' array $error_log of weet ik veel wat' zodat je later alle fout meldingen aan de gebruiker kan weergeven.
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
echo in return aangepast!
- Mark -
- Mark -
11 jaar geleden
 
0 +1 -0 -1
Aangezien je voorbeeld bedoeld is om tussen de body tags te plaatsen moet je wel nog even een echo voor showSQLError() plaatsen. Er wordt nu niets weergeven op deze manier.
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
Ook dit is aangepast. Indien de code toch buiten de body-tags word geplaatst zullen ze de tekst moeten opvangen in een var en echoën binnen de body-tags.
Bertus Wikkerink
Bertus Wikkerink
11 jaar geleden
 
0 +1 -0 -1
Jasper,
je hebt op mijn vraag 'PRIMARY KEY' gereageerd.
Daarbij vermeldde je dat 'or die' uit de tijd is en gaf een voorbeeld met een error afhandeling.
Jouw voorbeeld is echter voor mij niet te volgen.
Zou je ook het script dat ik gepost had kunnen gebruiken?
Dus in mijn script het gebruikte 'or die' vervangen en dan jouw foutafhandeling erin plaatsen. Vanaf de eerste regel tot en met de laatste?
Uiteraard het liefst met (zoals Wouter het meldde):
- Ik zou niet een script plaatsen en dan met comments aangeven wat er gebeurd. Ik zou elke regel/ 2 regels apart nemen en uitleggen wat er gebeurt.

Alvast bedankt voor de moeite.
Ik wil namelijk dolgraag van oudere oplossingen af als er betere zijn; maar dan wil ik wel kunnen volgen hoe ze werken. En als ik dan jouw uitleg met die van het cursusboek kan vergelijken, zal dit voor mij makkelijker zijn.

Groeten Bertus
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
ik zal proberen binnenkort de algemene structuur in stukken te kappen en te bespreken.
Bertus Wikkerink
Bertus Wikkerink
11 jaar geleden
 
1 +1 -0 -1
Alvast dank voor jouw moeite.

Bertus
Kees Schepers
kees Schepers
11 jaar geleden
 
Leuk initiatief het artikel maar het is in mijn ogen niet mooi in hoofstukjes opgedeelt. Artikeltjes hier zijn altijd maar 2 pagina's en that's it. Ik zou voorstellen om echt de moeite te nemen om een uitgebreid artikel te schrijven waarin je een aantal onderdelen duidelijk uitlegt.

Ook zoals al gezegd kun je denk ik beter dingen opdelen in kleine stukjes code en toelichting geven in gewone tekst in plaats van in de code.

Ook is het zeker niet onbelangrijk om ook iets te doen met de warnings die MySQL genereert ipv alleen de errors. Een warning word bijvoorbeeld gegevens als je een string waarde in een integer veld probeert te stoppen. In de niet strict modus werkt dit gewoon en word het naar 0 geconverteerd maar als je warnings niet uitleest kan het zijn dat je uren lang zoekt.

http://nl.php.net/manual/en/mysqli.get-warnings.php

In de MySQL extensie is hier geen functie voor maar je zou in een ontwikkel omgeving automatisch een query kunnen uitvoeren met SHOW_WARNINGS().

Succes!
Humor me
Humor me
11 jaar geleden
 
Aangezien queries over het algemeen nogal essentieel zijn voor je pagina en het normaliter niet hoort te gebeuren dat er iets fout gaat gebruik ik gewoon heel simpel:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
    /**
     * Query loskoppelen van je mysql statement is
     * handig voor debuggen als je met variabelen in je
     * queries werkt.
     */

    $query = 'SELECT * FROM `table` WHERE `column1` = 1';
    $result = mysql_query($query);

    if($result === false) {
        echo mysql_error();
    }
else {
        // Afhandeling van de overige code
    }
?>
Karl Karl
Karl Karl
11 jaar geleden
 
Lars Grevelink 13 minuten geleden:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
    /**
     * Query loskoppelen van je mysql statement is
     * handig voor debuggen als je met variabelen in je
     * queries werkt.
     */

    $query = 'SELECT * FROM `table` WHERE `column1` = 1';
    $result = mysql_query($query) or die(mysql_error());
?>

Alsjeblieft, heb je de tutorial wel gelezen? Wat een onzin. Dit is juist niet goed.
- Selecteer wat je wilt hebben, gebruik geen *.
- Backticks (`) horen NOOIT in sql thuis!
- Foutafhandeling ontbreekt!
'or die' is toch zo dom iets. Ik heb hier op phphulp.nl de volgende uitleg geïntroduceerd:
Als je iets fout doet, dan val jezelf toch ook niet dood?
(Uitzonderingen daargelaten.)
Waarom moet het script dan wel doodvallen. Je krijgt gewoon netjes een bepaalde waarde terug van de mysql_query functie, die kun je gebruiken in een if statement en klaar ben je.
En nog belangrijk: Toon nooit de php / sql fout aan de gebruikers!
Humor me
Humor me
11 jaar geleden
 
Komt ie:
- Als je alle kolommen gebruikt kan je vanzelfsprekend een asterix gebruiken
- Backticks kunnen zeker in je query staan, kijk bijvoorbeeld naar Zend als Framework, phpMyAdmin als database manager - zijn allemaal grote jongens, maar MySQL heeft het inderdaad niet in zijn documentatie staan.
- Foutafhandeling is daadwerkelijk aanwezig, maar kan inderdaad een stukje netter met een ifje.
- Daarnaast was het een voorbeeld query en zou je deze niet al te serieus moeten nemen.

Watch the attitude man. :)

Aangepast in origineel en zie code hieronder:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
    /**
     * Query loskoppelen van je mysql statement is
     * handig voor debuggen als je met variabelen in je
     * queries werkt.
     */

    $query = 'SELECT * FROM `table` WHERE `column1` = 1';
    $result = mysql_query($query);

    if($result === false) {
        echo mysql_error();
    }
else {
        // Afhandeling van de overige code
    }
?>
Pim -
Pim -
11 jaar geleden
 
1 +1 -0 -1
Zo'n onzin is het niet. Altijd mysql_error() aan de gebruiker tonen is echt een groot gevaar voor je veiligheid...
Humor me
Humor me
11 jaar geleden
 
Ik gebruik altijd een server om te ontwikkelen en een andere voor productie. Hierdoor ondervang je ten aller tijde dat de errors de gebruiker bereiken tijdens de ontwikkel periode en je productie code zou geen errors moeten bevatten. Voor jezelf als ontwikkelaar maakt het niet echt veel uit als je je eigen datastructuur ziet. :)
Pim -
Pim -
11 jaar geleden
 
0 +1 -1 -1
Maar waarom zou je dan niet gewoon eoa abstractielaag eroverheen doen, zodat je eenvoudigweg een debug-mode aan of uit kan zetten?
Op deze manier bestaat altijd de mogelijkheid dat je er een vergeet...
Jasper DS
Jasper DS
11 jaar geleden
 
0 +1 -0 -1
Lars, moet je nu echt mijn tut vol spammen met foute informatie? 'Als je alle kolommen gebruikt kan je vanzelfsprekend een asterix gebruiken' is niet juist! Bij SQL moet je alles typen wat je doet, ook voor de snelheid is een wildcard (*) gebruiken niet goed! Lees eerst de tutorial nog maar eens goed en daarna alles wat karl heeft geschreven. Daar kan je precies nog veel van leren.
Victor Php
Victor Php
11 jaar geleden
 
1 +1 -0 -1
Lars Grevelink op 04/03/2011 17:35:31:
- Als je alle kolommen gebruikt kan je vanzelfsprekend een asterix gebruiken
- Backticks kunnen zeker in je query staan, kijk bijvoorbeeld naar Zend als Framework, phpMyAdmin als database manager - zijn allemaal grote jongens, maar MySQL heeft het inderdaad niet in zijn documentatie staan.


Als je alle kolommen gebruikte kan je vanzelfsprekend een (lees: geen) asterix gebruiken
en je moet ook NOOIT backticks (`) gebruiken in een query!


-edit-
Lees net je profiel.
Je hebt eigen bedrijf.. lever je dan ook werk met backticks, wildcards en zonder foutafhandeling?
Humor me
Humor me
11 jaar geleden
 
Ik bouw alles in Zend. Daarnaast het volgende, het script is nice, never commented on that. Als iemand na de post van mijn code, in ieder geval vertelde waarom ik dan geen backticks zou moeten gebruiken of asterix - dan zou ik ook nog wat kunnen leren van dit geheel. Asterix snap ik wel, maar snap niet waarom de backticks zo'n probleem zijn. Dan alleen nog de vraag; waarom zetten frameworks als Zend en database managers als phpMyAdmin dan wel de backticks in hun queries? Just curious.

Regards.

Edit
Wat ik opmaak uit verschillende artikelen op verschillende fora - is het voornamelijk foutgevoeligheid, maar als je ze consistent gebruikt wat zijn dan de andere problemen?
Serge Girard
Serge Girard
10 jaar geleden
 
0 +1 -0 -1
Ik ben nieuw in PHP maar heb wel zo'n 20jaar SQL ervaring op IBM mainframe (DB2). Uiteraard wordt een SQL fout NOOIT aan de eindgebruiker getoond. De foutafhandeling is redelijk simpel:
if (!$OK):
sql_errors ($wprog_nm, '002', mysql_errno(), mysql_error() , $sql );
endif;
$wprog_nm is naam van het programma, '002' is manueel volgnummer, de rest is bekend. De functie zelf verstuurd een email naar de beheerder die dan redelijk snel het juiste SQL statement (adhv volgnummer) kan terugvinden. Deze manier wordt reeds jaren succesvol toegepast.
TJVB tvb
TJVB tvb
10 jaar geleden
 
1 +1 -0 -1
Serge, je hebt geheel gelijk.
Maar veel mensen hier willen graag aan iedereen laten zien wat er fout gaat en meteen het script slopen.

Backticks zijn net als de ob_* functies een pleister middel om je echte fouten te verbergen.

Dat Zend, phpmyadmin etc het gebruiken is omdat veel mensen toch graag gereserveerde woorden willen gebruiken.
En anders gaat SELECT deleted FROM update fout.

Het gebruik van * is uit den boze, als je kolommen toevoegt haal je te veel data op. Dat is zonde voor de performance, ook moet je dan de database er bij halen om te zien welke data er opgehaald wordt.
Bertus Wikkerink
Bertus Wikkerink
10 jaar geleden
 
0 +1 -0 -1
Aan allen,
ik blijf PHP leuk vinden.
Ook blijf ik maar een hobby'ist.
(NB. Ik heb ook nog een beroep, een gezin en kleinkind.)

Dit item is voor mij al weer voorbij.

Hierbij wil ik dit dan ook als gesloten beschouwen.
Dank aan jullie allen voor jullie inbreng.

Groeten,

Bertus
Serge Girard
Serge Girard
10 jaar geleden
 
0 +1 -0 -1
Jammer, want ik wil graag meer dan een hobby´ist zijn... PHP moet echt zeer professioneel gedaan worden anders wordt het een zooitje..!
Bertus Wikkerink
Bertus Wikkerink
10 jaar geleden
 
0 +1 -0 -1
Aan allen,

ik vind het zelf ook jammer. Want er is duidelijk behoefte om zo met elkaar van gedachten te wisselen.

Wel zou ik graag zien dat die mensen die al wat verder zijn met PHP verwijzen naar documentatie over het onderwerp waar ze op reageren en/of
dat ze met voorbeelden duidelijk maken wat ze bedoelen. EN dat we daarbij veel gebruik maken van (//Uitleg...) over het onderdeeltje van het gebruikte script.
Dit is voor de nieuwkomers in PHP veel duidelijker dan dat jullie elkaar afvallen.

Nogmaals groeten van:

Bertus

PS: Het gezamwlijk schrijven via dit medium zou misschien kunnen leiden tot een geweldige documentatie over hoe PHP te gebruiken. (Al dan niet in samenwerking met bv SQL)
maw Je schrijft dan gezamelijk een nieuw boek over PHP.
Jordi Kroon
Jordi Kroon
10 jaar geleden
 
1 +1 -0 -1
Ik wil niet lullig doen maar als een beginnende php scripter iets post. Ga ik ervan uit dat ze eerst opzoeken waar de fout licht en onbekende functies opzoekt . Ipv dat wij een link moeten geven naar de documentatie die ze zelf ook kunnen lezen :)
Bertus Wikkerink
Bertus Wikkerink
10 jaar geleden
 
1 +1 -0 -1
Beste Jordi,
dank voor je reactie.
Maar wij beginners weten vaak niet waar naar te zoeken.
We hebben dan vaak al bijna alle functies twee tot drie keer bekeken.

Zo zocht ik naar een fout in de syntaxis van een query omdat ik die melding terugkreeg van de parser.
Door hulp en een geweldige tip van 1 van jullie:
een script om fouten op te lossen en een voorbeeld met de functie var_dump
Nu kan ik ook vaker zelf een fout vinden in mijn query's.

Ik was zelf nooit op de functie var_dump gekomen.
Ik was al zes weken bezig met van allerlei functies uit te proberen om een oplossing te vinden.
Hierbij moet ik vermelden dat ik een beginner ben en derhalve vanuit die positie al niet weet welke functie ik voor een bepaald probleem nodig heb.

Ik ben dan ook zeer dankbaar voor deze site en ZEKER ZEER DANKBAAR VOOR JULLIE MOEITE MET BEGINNERS ZOALS IK.

Ik krijg echter vaak oplossingen die jullie elkaar als ervaringsdeskundigen zouden kunnen geven.
Ik begrijp dan vaak niet wat ik met die oplossingen aan moet.

Dus blijf ik hopen dat jullie de moeite blijven nemen.

Daarom ook aan jullie allemaat,

HEEL, HEEL , HARTELIJK DANK VOOR JULLIE MOEITE
Serge Girard
Serge Girard
10 jaar geleden
 
1 +1 -0 -1
Deze topic gaat over SQL foutafhandeling....
Jordi Kroon
Jordi Kroon
10 jaar geleden
 
@bertus Ik hoor je even hard zonder hoofdletters.
Niels K
Niels K
10 jaar geleden
 
Je eventueel de Ternary Operator (verkorte if/else notatie) in je functie kunnen gebruiken.
Mebus  Hackintosh
Mebus Hackintosh
9 jaar geleden
 
Heel leuk dat er gekeken word of een insert query is gelukt maar weet je ook zeker of de record is toegevoegd aan de tabel? Gebruik daarom ook mysql_affected_rows().
Donny Wie weet
Donny Wie weet
9 jaar geleden
 
1 +1 -0 -1
Zo duidelijk als wat. Heb het dit keer doorgelezen en makkelijker als dit kan niet :) Thanks! :)
 - Diov  -
- Diov -
7 jaar geleden
 
0 +1 -0 -1
Sorry dat ik op een topic van 4 jaar geleden reageer,
maar zou het niet handig zijn als deze tutorial ook in mysqlI komt?
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Verwijderd 31683
Verwijderd 31683
5 jaar geleden
 
1 +1 -0 -1
Omdat hier nog steeds aan gerefereerd wordt:
- hierboven staat ergens dat je $var === false zou kunnen vervangen door !$var, maar afhankelijk van de waarde van $var zou dat nog wel eens hele verschillende dingen op kunnen leveren - deze twee varianten zijn NIET vrij uitwisselbaar!

- $sql (in de functie die de rode draad door deze tutorial vormt) bevat mogelijk user input; deze zou zodoende ook (in de HTML context) ge-escaped moeten worden met htmlspecialchars (met de goede character encoding, zie ook hieronder)

- de hele discussie over het veilig omgaan met queries mede door gebruikmaking van _real_escape_string() functionaliteit is zinloos zonder de behandeling van character encoderingen; zonder een correcte gebruikmaking hiervan (met behulp van _set_charset() functies direct na het maken van een connectie) is namelijk niet gegarandeerd dat _real_escape_string() zijn werk goed doet.

Om te reageren heb je een account nodig en je moet ingelogd zijn.

Inhoudsopgave

  1. Algemene structuur
  2. Voorbeeld 1 - Het ophalen van gegevens
  3. Voorbeeld 2 - Invoeren van gegevens
  4. Samenvatting

Labels

PHP tutorial opties

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.