MySQL query foutafhandeling

ICTscripters maakt gebruik van cookies. Door het gebruiken en browsen naar onze site gaat je automatisch akkoord met het gebruik van cookies. Klik hier voor meer informatie

  • Beste ICT'ers,

    Omdat ik zie dat vaak goede foutafhandeling ontbreekt heb ik besloten om deze tutorial te maken. Je zult in deze tutorial leren hoe je een goede query foutafhandeling maakt en hoe je deze kan loggen.

    1 Foutafhandeling
    2 Error logging
    3 Class
    4 Frameworks

    1.0 Foutafhandeling

    1.1 Geen foutafhandeling

    Ik zal beginnen met het geven van een fout voorbeeld.

    PHP Source Code

    1. <?php
    2. $query = "SELECT * FROM database";
    3. mysql_query($query);
    4. ?>


    Je zult geen melding zien en er gebeurt niks. Je kan op deze manier niet debuggen. We hebben dus een foutafhandeling nodig.

    1.1 Or die()

    Ik zal nog een voorbeeld laten zien die je ook niet moet gebruiken.

    PHP Source Code

    1. <?php
    2. $query = "SELECT * FROM database";
    3. mysql_query($query) or die(mysql_error());
    4. ?>


    Je hebt nu een foutafhandeling waarmee je kan debuggen, maar die niet gewenst is. Je kan or die() beter niet gebruiken. Een aantal redenen om or die() niet te gebruiken:

    - Het geeft een lelijke error aan de user.
    - In combinatie met mysql_error() geeft het informatie die een gebruiker niet zou moeten weten
    - Je kan de error niet loggen
    - De error zal altijd op het scherm staan. Je kan er niet voor kiezen om het te verbergen.
    - Het stopt het script abrupt.

    1.3 Basic foutafhandelen

    Hoe moet je het dan wel doen? Je wil een nette response aan de gebruiker geven. Het volgende voorbeeld zal laten zien hoe je dat moet doen.

    PHP Source Code

    1. <?php
    2. $query = "SELECT * FROM database";
    3. //If statement. Als de query de boolean FALSE teruggeeft een response geven.
    4. if(!mysql_query($query))
    5. {
    6. echo 'Er ging iets mis. Excuses voor het ongemak!';
    7. }
    8. else
    9. {
    10. //Rest van het script
    11. }
    12. ?>
    Laat alles zien


    Nu laat je een nette error zien. Het nadeel hiervan is, is dat je niet weet wat de error is. Je hebt hem niet gelogd. Er zijn een aantal manieren om een error te loggen.

    2.0 Error logging

    Je wilt je errors loggen, zodat je deze kan bekijken. Van hieruit kan je je code debuggen. Alleen hoe moet je errors loggen? Ik geef hier een aantal voorbeelden. Ik heb expres geen MySQL logging gebruikt, omdat je ervan uit moet gaan dat als je een mysql error krijgt je de database niet kan gebruiken.

    2.1 Error loggen in een bestand

    Ik laat je hier zien hoe je een logbestand maakt.

    PHP Source Code

    1. <?php
    2. //Query
    3. $query = "SELECT * FROM database";
    4. //Checken of de query is gelukt
    5. if(!mysql_query($query))
    6. {
    7. //Query is mislukt. Afhandelen
    8. //De gebruiker een nette response geven
    9. echo 'Er ging iets mis op deze pagina. De error is bekend en wordt zo snel mogelijk opgelost. Excuses voor het ongemak!';
    10. //Bestandsnaam
    11. $bestand = "errors/log_index.txt";
    12. //Bestand openen. Als het bestand nog niet bestaat wordt het aangemaakt.
    13. $log_openen = fopen($bestand, 'a');
    14. //De error
    15. $error = date("d-m-Y G:i").' - '.mysql_error().' in query: '.$query;
    16. //De error naar het bestand schrijven
    17. fwrite($log_openen, $error);
    18. //Het bestand sluiten
    19. fclose($log_openen);
    20. }
    21. else
    22. {
    23. //Query is gelukt
    24. //Rest van het script
    25. echo 'Alles ging goed!';
    26. }
    27. ?>
    Laat alles zien


    De errors worden gelogd in een text file die je zo kan openen.
    Het enige wat je hierbij hoeft te doen is een errors map maken. De foutmelding word daar automatisch ingezet. Op deze manier heeft de user een nette response en heb jij de error zodat je deze kan oplossen.

    //Bramieboy100
    De datum staat nu ook in de error log.

    Voorbeeld error:

    27-01-2013 14:55 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'database' at line 1 in query: SELECT * FROM database



    3.0 Class

    Tips voor het verbeteren van deze class zijn altijd welkom!

    3.1 De class

    PHP Source Code

    1. <?php
    2. class database extends logging
    3. {
    4. public $res;
    5. protected $error;
    6. public function database ($user, $pass, $database)
    7. {
    8. if (!mysql_connect('localhost', $user, $pass) || !mysql_select_db ($database))
    9. echo 'Er ging iets mis. De error is bekend en er word gewerkt aan een oplossing. Excuses voor het ongemak!';
    10. }
    11. public function run_query ($sql)
    12. {
    13. $this->res = mysql_query ($sql);
    14. if (!$this->res)
    15. {
    16. echo "Er ging iets mis. De error is bekend en er word gewerkt aan een oplossing. Excuses voor het ongemak!<br />\r\n";
    17. $error = date("d-m-Y G:i").' - '.mysql_error().' in query: '.$sql;
    18. $bestand = "errors/log_index.txt";
    19. parent::logg($bestand, $error);
    20. }
    21. else
    22. {
    23. return $this->res;
    24. }
    25. }
    26. }
    27. class logging
    28. {
    29. public function logg ($bestand, $error)
    30. {
    31. $log_openen = fopen($bestand, 'a');
    32. fwrite($log_openen, $error."\r\n");
    33. fclose($log_openen);
    34. }
    35. }
    36. ?>
    Laat alles zien




    4.0 Frameworks

    Frameworks zorgen ervoor dat je veel niet zelf hoeft te doen. Ze nemen werk uit handen en dat kan tijd en ruimte besparen.

    4.1 Klogger

    Toevoeging van: Stefan.J

    Link: github.com/katzgrau/KLogger


    KLogger is an easy-to-use logging class for PHP. It supports standard log levels like debug, info, warn, error, and fatal. Additionally, it isn't naive about file permissions (which is expected). It was meant to be a class that you could quickly include into a project and have working right away.

    The class was written in 2008, but I have since received a number of emails both saying 'thanks' and asking me to add features.

    This github project will host the development of the next version of KLogger. The original version of KLogger is tagged as version 0.1, and is available for download here.


    4.2 CodeIgniter

    Toevoeging van: Tim

    Link: ellislab.com/codeigniter

    CodeIgniter heeft ook een error log functie. Standaard staat die op error reporting all. Dit kan je uitzetten als de site online staat. De errors worden dan nog gewoon gelogd.
    In de user guide (ellislab.com/codeigniter/user-guide/general/errors.html) staat informatie over het loggen.




    Als iets niet helemaal duidelijk is of jullie hebben nog wat toe te voegen hoor ik dat graag.

    Met vriendelijke groeten,

    Victor
    Met vriendelijke groet,

    Victor
    Beheerder ICTscripters

    1,951x gelezen

Reacties 11

  • victor -

    Klopt, maar je zou de classes ook apart kunnen gebruiken. Je kan ook andere dingen loggen.

  • bramieboy100 -

    Ik heb niet erg veel op aan te merken aan je class maar een class is toch handiger. Alleen maak je de functies met een prefix. db_functienaam bijvoorbeeld voor alle MySQL dingen en logg hoeft niet perse een prefix.

  • victor -

    @Stefan

    Ik ga even kijken hoe ik die visibility moet toepassen. Dat gaat wel lukken denk ik.
    Moet ik er dan 2 classes van maken? Éen database class en een logg class.

    //

    Ik heb de class aangepast. Ben alleen nog niet toegekomen aan de visibility modifiers.

    //

    Nu ook de visibility modifiers toegevoegd. Ik heb wel een vraagje. Moet ik élke variabele die ik binnen de class aanspreek boven aan de code zetten?

  • Stefan.J -

    Je class maakt nog geen gebruik van visibility modifiers (public/protected/private), doe dat wel. Daarnaast, logging heeft niks met de database te maken, en hoort dus ook zeker niet in een class Database.

  • victor -

    @Bramieboy100

    Bedankt voor je opmerking! Had ik even overheen gekeken. Werk ook niet zo vaak met fopen, dus moest ook alles even nachecken.

    Kan je ook even kijken naar mijn "class"? Deze is nog verre van bruikbaar, maar weet niet of ik in de goede richting aan het denken ben qua OOP.

    Heb het even aangepast ;)

    Groeten,

    Victor

  • bramieboy100 -

    Er zit een fout in, kom ik nu pas achter maar je moet de w in een a veranderen in fopen. Nu delete hij de heletijd de error en komt een nieuwe voor in de plaats. Even nagezocht:
    Write: 'w'
    Open a file for write only use. In addition, the data in the file is erased and you will begin writing data at the beginning of the file. This is also called truncating a file, which we will talk about more in a later lesson. The file pointer begins at the start of the file.

    Append: 'a'
    Open a file for write only use. However, the data in the file is preserved and you begin will writing data at the end of the file. The file pointer begins at the end of the file.

  • victor -

    @Stefan
    Het lijkt me ook niet echt wenselijk om 40 queries uit te voeren. Dan gaat er waarschijnlijk toch iets mis.
    Als je toch zoveel queries nodig hebt kan je inderdaad beter een framework gebruiken.

    Dit is één van de vele manieren om te loggen. Het leek mij het makkelijkst voor beginners aangezien je niet meteen met frameworks wil gaan beginnen. Het nadeel hiervan is bijvoorbeeld dat het niet werkt als je een parse error hebt.

    @Koen en Stefan
    Bedankt voor jullie reacties. Ik zal alle informatie er even bij zetten. ;)

    //

    Je zou hier overigens ook een functie van maken bedenk ik me net. Ik ga deze tutorial verder uitbreiden zodat deze voor beginners en gevorderden een goed artikel is om te lezen.

    //

    Ik heb de class toegevoegd. Heb nu namelijk geen tijd meer. Als jullie er opmerkingen over hebben hoor ik dat graag. De class is nog niet helemaal af.

  • K.Rens -

    Goed artikel, perfect voor beginners.
    Je bespreekt duidelijk de basis van het loggen.

    Voor de gevorderden is de reactie van Stefan perfect, met die frameworks kun je inderdaad alles beter loggen en kun je code gebruiken die herbruikbaar is.

    @Bramieboy: goede reactie, datum is inderdaad nuttig om te weten.
    Ik zie dat Victor het er bij heeft gezet.

  • Stefan.J -

    Stel je nu eens voor dat je een pagina hebt waarop 40 verschillende query's mogelijk worden uitgevoerd. Op deze manier levert je dat dan dus 40 if/else statements op ? Lijkt me niet heel wenselijk, je programmeert je dan een ongeluk.

    Mocht je gebruik kunnen maken van PDO, dan heeft deze library daar een veel betere oplossing voor, exceptions: php.net/manual/en/pdo.error-handling.php

    Logging zal ik ook niet zelf doen. Er zijn, ook voor PHP, best wel logging frameworks te vinden die logging voor je kunnen oplossen. Je gaat toch niet in al die 40 if/else statements een file openen?

    Voor logging frameworks:
    codefury.net/2008/07/klogger-a-simple-logging-class-for-php/
    stackoverflow.com/questions/341154/php-logging-framework

  • victor -

    Ga ik aanpassen. ;) Je zou als je de error hebt opgelost het bestand kunnen verwijderen. Het bestand word namelijk aangemaakt als het nog niet bestaat.

  • bramieboy100 -

    Ik deze tutorial goed. Alleen wat ik mis is dat je de tijd en de datum niet in het logbestand schrijft. Dit is namelijk handig, want als er een probleem bekend is en je lost het op en je ziet dat in het logbestand, ga je proberen om het op te lossen maar je ziet de fout niet.