Correcte foutenafhandeling

Wanneer je met PHP werkt kan er natuurlijk altijd iets mis gaan. Dat is niet erg wanneer je aan het debuggen bent, maar een fout tonen aan de gebruiker is zachtgezegd niet netjes. Een gebruiker kan hier vaak niks mee, en vooral voor hackers is het nuttige informatie om systemen te kraken.

Waar pas je foutenafhandeling toe?
Je past foutenafhandeling in principe toe op dingen die fout zouden kunnen gaan. Denk hierbij aan de volgende voorbeelden:

  • MySQL statements
  • Uploaden van bestanden
  • Ophalen van externe content (denk aan een API)

Dit soort fouten kun je in de meeste gevallen opvangen met een if-statement. Complexere applicaties kun je vaak beveiligen door middel van een try ... catch constructie (lees: php.net), maar daar gaan we ons hier niet mee bezig houden. Wij houden het op het eerste voorbeeld: MySQL statements.

Fouten onderdrukken
Sommige 'programmeurs' lossen hun problemen vaak op met smerige fixes die de fout niet oplossen. Op zo'n moment onderdrukken ze de fout dus, waardoor de fout niet echt verholpen is en PHP of MySQL er fouten voor genereert, maar ze worden gewoon onderdrukt om extra beveiliging te vermijden. De fout is er op dat moment dus nog wel, alleen wordt hij onderdrukt - en dat is uit den boze!

Hoe onderdruk je een fout?
Een fout onderdruk je simpelweg door hem óf niet op te vangen (dus zonder if-statement of try ... catch constructie), of door er een speciaal teken voor te zetten: een apenstaart (@). Hiervan een voorbeeld met een e-mail die verstuurd moet worden:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
// Verstuur een mail naar een klant
@mail($sOntvanger, $sOnderwerp, $sBericht, $sHeaders);
echo 'De e-mail is verstuurd!';
?>

Je ziet dat er een @ voor de functie mail staat. Dit betekent letterlijk:
Probeer het maar, maar als het fout gaat, geef dan geen fout.

Een ander voorbeeld is het gebruik van rare buffer fixes. Veel beginners krijgen wel eens de 'header already sent'-fout te zien, en hen wordt dan verzocht bovenin hun code ob_start te zetten zodat de fout onderdrukt wordt - hij is dan dus niet opgelost!

Meer over 'headers already sent'-fouten: klik hier

Waarom foutenafhandeling?
Nette foutenafhandeling is noodzakelijk omdat je geen vreemde (of voor hackers informatieve) teksten op het scherm wilt tonen. Het is daarom de bedoeling dat je je fouten netjes opvangt en een nette melding op het scherm van de gebruiker toont.

Voorbeeld in een MySQL statement
In MySQL maken mensen vaak gebruik van de functie mysql_query (deze functie hebben we in een paar pagina's hiervoor besproken). Deze functie wordt gebruikt om een query naar de MySQL server te sturen. Wat beginners vaak doen, is het opvangen van fouten op een groffe manier afhandelen, (met die en mysql_error) door het parsen van de pagina direct af te breken en een smerige fout naar de gebruiker te gooien. Op deze manier stopt PHP direct met het parsen van de pagina. Een voorbeeld daarvan is dat je layout onder de foutmelding niet meer afgemaakt wordt, wat niet de bedoeling is. Dit is hiervan een voorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
mysql_query("SELECT nsaam FROM klanten") or die (mysql_error());
?>


Let op de typfout 'nsaam', wat tijdens het openen van de pagina de volgende melding zou moeten geven:
#1054 - Unknown column 'nsaam' in 'field list'

Dit is iets wat een gebruiker niet hoort te zien. We gaan daarom met een if-statement de melding opvangen en een nette melding op het scherm tonen.
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
16
17
18
19
20
<?php
// Query netjes in een variabele zetten zodat je hem eventueel later kunt loggen, mocht het fout gaan
$sQuery = "
            SELECT
                nsaam
            FROM
                klanten
"
;
$qSql = mysql_query($sQuery);
// Controleren of de query succesvol uitgevoerd is
if ($qSql === false)
{

    echo 'De klanten kunnen niet opgehaald worden, probeer het later opnieuw!';
    // Eventueel loggen van de error
}
else
{
    echo 'Het ophalen van de klanten is gelukt!';
}

?>


Nu krijgt de gebruiker de volgende melding op het scherm:
De klanten kunnen niet opgehaald worden, probeer het later opnieuw!

Dat is een stuk netter, en bovendien krijg je in je true-scope (regel 13 en 14) de mogelijkheid om de fouten eventueel te loggen zodat je ze makkelijk op kunt lossen.

Gebruik van or die en mysql_error
Het gebruik van or die is dus uit den boze! Let er ook op dat de gebruiker geen mysql_error te zien krijgt. Deze twee dingen mogen duidelijk zijn! (mysql_error kun je overigens wél gebruiken om eventueel een foutmelding te loggen)

Referenties

« Lees de omschrijving en reacties

Inhoudsopgave

  1. Leesbaarheid
  2. SQL-injection
  3. XSS-injection
  4. Gebruik van backticks in MySQL
  5. Correcte foutenafhandeling
  6. Geheugenefficiënt programmeren
  7. Slot

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.