Foutafhandeling in PHP (Error Handling)
- Inleiding
- Weergave en interpretatie van PHP fouten
- Basis foutafhandeling met die()
- Een flexibelere manier: trigger_error()
- Foutafhandeling en controle van variabelen
- Een eigen foutafhandeling functie met set_error_handler()
- Exceptions in PHP 5
- Gedetailleerde foutinformatie verkrijgen met exceptions
- Uitgebreide foutafhandeling met gebruik van foutcodes
- Uitbreiden van de standaard Exception klasse
- Slotwoord en referenties
- Reacties op deze tutorial
Een eigen foutafhandeling functie met set_error_handler()
Hoewel trigger_error() ons in staat stelt om al veel gedetaileerdere foutmeldingen te geven, wordt er nog steeds gebruik gemaakt van de standaard error handler van PHP. We zitten dus nog altijd vast aan die standaard foutmeldingen van PHP.Gelukkig biedt PHP ons ook de mogelijkheid om zelf een functie te schrijven die de foutafhandeling voor ons kan verzorgen en die de standaard error handler van PHP kan vervangen. De syntax van zo'n functie moet altijd als volgt zijn:
Code
1
2
3
2
3
<?php
function error_functie (level, message, file, line, context)
?>
function error_functie (level, message, file, line, context)
?>
De verschillende parameters, waarvan de eerste twee verplicht zijn, hebben de volgende waarden:
- level - Geeft het level van de fout weer. Zie hieronder voor de waarden
- message - De foutmelding die gegenereerd wordt
- file - De bestandsnaam waarin de fout opgetreden is
- context - Een array waarin alle variabelen en hun waarden ten tijde van de fout
De waarden van het level van de fout zijn als volgt:
- E_WARNING - 2
- E_NOTICE - 8
- E_USER_ERROR - 256
- E_USER_WARNING - 512
- E_USER_NOTICE - 1024
- E_RECOVERABLE_ERROR - 4096
- E_ALL - 8191
Voor het schrijven van de functie zijn deze waarden niet echt van belang. Zodra de functie namelijk aangeroepen wordt, dat zoals we later zullen zien onder andere ook met trigger_error() kan, worden de parameters van de functie automatisch gevuld.
Laten we eens kijken naar een eenvoudig voorbeeld van een eigen foutafhandeling functie en de toepassing ervan in een script:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
function myErrorHandler($errno, $errstr)
{
echo 'Er is een fout opgetreden<br />';
echo 'Foutlevel: '.$errno.'<br />';
echo 'Foutmelding: "'.$errstr.'"';
}
set_error_handler('myErrorHandler');
// Dit zal een foutmelding opleveren:
echo $var;
?>
ini_set('display_errors', 'On');
error_reporting(E_ALL);
function myErrorHandler($errno, $errstr)
{
echo 'Er is een fout opgetreden<br />';
echo 'Foutlevel: '.$errno.'<br />';
echo 'Foutmelding: "'.$errstr.'"';
}
set_error_handler('myErrorHandler');
// Dit zal een foutmelding opleveren:
echo $var;
?>
De output van dit scriptje is de volgende:
Code
1
2
3
2
3
Er is een fout opgetreden
Foutlevel: 8
Foutmelding: "Undefined variable: var"
Foutlevel: 8
Foutmelding: "Undefined variable: var"
Zoals verwacht wordt er een foutmelding gegenereerd omdat $var niet bestaat. Nu wordt echter in plaats van de standaard php foutmelding, onze eigen foutmelding weergegeven.
Uiteraard is deze melding lang niet zo uitgebreid als de standaard php foutmelding, maar het pricipe moge duidelijk zijn. Een voorbeeld van een iets uitgebreideren functie zie je hieronder:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
function myErrorHandler($iLevel, $sMessage, $sFile, $iLine)
{
$aLevels = array(
2 => 'WARNING',
8 => 'NOTICE',
256 => 'FATAL ERROR',
512 => 'WARNING',
1024 => 'NOTICE' );
if(array_key_exists($iLevel, $aLevels))
{
$sLevel = $aLevels[$iLevel];
}
else
{
$sLevel = 'ONBEKENDE FOUT';
}
echo 'Er is een fout opgetreden!<br />';
echo 'Foutsoort: '.$sLevel.'<br />';
echo 'Foutmelding: '.$sMessage.'<br />';
echo 'Bestand: '.$sFile.'<br />';
echo 'Regel: '.$iLine.'<br />';
if($iLevel == 256)
{
echo 'Script wordt gestopt...';
exit();
}
}
set_error_handler('myErrorHandler');
// Een foutmeling triggeren:
trigger_error('Dit is een voorbeeld foutmelding', E_USER_ERROR);
?>
ini_set('display_errors', 'On');
error_reporting(E_ALL);
function myErrorHandler($iLevel, $sMessage, $sFile, $iLine)
{
$aLevels = array(
2 => 'WARNING',
8 => 'NOTICE',
256 => 'FATAL ERROR',
512 => 'WARNING',
1024 => 'NOTICE' );
if(array_key_exists($iLevel, $aLevels))
{
$sLevel = $aLevels[$iLevel];
}
else
{
$sLevel = 'ONBEKENDE FOUT';
}
echo 'Er is een fout opgetreden!<br />';
echo 'Foutsoort: '.$sLevel.'<br />';
echo 'Foutmelding: '.$sMessage.'<br />';
echo 'Bestand: '.$sFile.'<br />';
echo 'Regel: '.$iLine.'<br />';
if($iLevel == 256)
{
echo 'Script wordt gestopt...';
exit();
}
}
set_error_handler('myErrorHandler');
// Een foutmeling triggeren:
trigger_error('Dit is een voorbeeld foutmelding', E_USER_ERROR);
?>
Met dit script zal de output zijn:
Code
1
2
3
4
5
6
2
3
4
5
6
Er is een fout opgetreden!
Foutsoort: FATAL ERROR
Foutmelding: Dit is een voorbeeld foutmelding
Bestand: C:\wamp\www\test.php
Regel: 39
Script wordt gestopt...
Foutsoort: FATAL ERROR
Foutmelding: Dit is een voorbeeld foutmelding
Bestand: C:\wamp\www\test.php
Regel: 39
Script wordt gestopt...
Ook deze functie is eigenlijk nog vrij beperkt, maar ik denk dat het wel een kleine indruk geeft van de mogelijkheden die er zijn.
Zo zou je er bijvoorbeeld voor kunnen kiezen om niet de precieze foutmelding op het scherm te zetten, maar deze via mail te versturen, aan een error log toe te voegen of weg te schrijven naar een database. Zolang je ervoor zorgt dat de syntax van de functie in stand blijft, kun je de foutafhandeling van jouw scripts helemaal naar je eigen wensen aanpassen.
Ontwikkelfase vs. Productiefase
Een belangrijk iets waar je rekening mee moet houden bij het toepassen van een type foutafhandeling, is de fase waarin je website verkeerd. In de ontwikkelfase ben je nog volop bezig met het bouwen en debuggen van je website. In deze fase wil je foutmeldingen dan ook zo gedetailleerd mogelijk op het scherm hebben. In de productiefase daarentegen, de fase waarin het grote publiek toegang heeft tot je website, wil je dat natuurlijk niet. Dan wil je dat de gebruiker enkel een nette foutmelding krijgt en dat de gedetailleerde foutmelding weggeschreven wordt in een log of bijvoorbeeld naar je gemaild wordt.
Dit valt allemaal te regelen met je eigen foutafhandeling functie. Pas deze dus aan of gebruik verschillende functies in de verschillende fases!