Foutafhandeling in PHP (Error Handling)

Door Joren de Wit, 14 jaar geleden, 14.885x bekeken

De basis van ieder PHP script!

Gesponsorde koppelingen

Inhoudsopgave

  1. Inleiding
  2. Weergave en interpretatie van PHP fouten
  3. Basis foutafhandeling met die()
  4. Een flexibelere manier: trigger_error()
  5. Foutafhandeling en controle van variabelen
  6. Een eigen foutafhandeling functie
  7. Exceptions in PHP 5
  8. Gedetailleerde foutinformatie verkrijgen
  9. Uitgebreide foutafhandeling met gebruik van foutco
  10. Uitbreiden van de standaard Exception klasse
  11. Slotwoord en referenties

 

Er zijn 34 reacties op 'Foutafhandeling in php error handling'

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
- -
- -
14 jaar geleden
 
1 +1 -0 -1
Een dikke vette 10!

Trouwens, ik vraag me wel af hoe je exceptions toe moet passen in het MVC model, stel er gaat iets fout in het model, waar vang je dat op? In de controller of de view?
Jelmer -
Jelmer -
14 jaar geleden
 
0 +1 -0 -1
Controller zou ik daarvoor gebruiken. Tis business-logica, en alleen in de controller zou je een alternatieve route kunnen aanmaken (zoals een andere view aanroepen die mooie melding geeft)

Daarnaast, Don't Repeat Yourself. Als je het in je View wil afvangen, zal je in al je views dus een soort van catch-blok moeten bouwen. En wat was je van plan te gaan doen met je error in de view? Weergeven? Misschien kan je wel veel nuttigere dingen ermee doen zoals zoeken naar een alternatief model dat wel doet (zeg maar een "pagina niet gevonden, zocht je deze misschien?" situatie)

Vang je Exceptions pas op op het punt waar je een alternatief kan aanbieden. Heb je geen alternatief, dan laat je het gewoon door-vallen.
TJVB tvb
TJVB tvb
14 jaar geleden
 
0 +1 -0 -1
Nette tutorial!

Maar behalve een eigen fout afhandeling heb je ook nog de mogelijkheid voor een algemene exception handler voor alle niet opgevangen exceptions.
http://php.net/set_exception_handler
Joren de Wit
Joren de Wit
14 jaar geleden
 
0 +1 -0 -1
@TJVB: daar heb je gelijk in, ik heb er een stukje over toegevoegd aan de tutorial.

Ik ben echter van mening dat je deze functie alleen moet gebruiken tijdens de ontwikkelfase waarin je een gedetailleerde foutmelding geeft bij een niet afgevangen exception. Zodra je script in een productieomgeving terecht komt, moet je gewoon zorgen dat alle exceptions netjes afgevangen worden...
TJVB tvb
TJVB tvb
14 jaar geleden
 
0 +1 -0 -1
Dat ben ik op zich met je eens maar ik laat er dan toch liever een systeem voor de zekerheid die alle errors (net als alle gewone errors afvangt) en opslaat in een logfile met alle info.
Zo zorg ik ervoor dat als ik een fout gemaakt hebt de bezoeker daar geen last van heeft. (En met een cronjob controleer ik die bestanden zodat als er iets instaat ik een mailtje krijg)
Gewoon als een soort extra vangnet.
PHP Newbie
PHP Newbie
14 jaar geleden
 
0 +1 -0 -1
Wauw
Robert -
Robert -
14 jaar geleden
 
0 +1 -0 -1
Zeer goede tutorial, hier heb ik nog wat aan.
Alles heel erg netjes en duidelijk uitgelegd.
Robert Deiman
Robert Deiman
14 jaar geleden
 
0 +1 -0 -1
Mooie tut Blanche! Wel ff een foutje op pagina 7 eruit halen:

"Een andere manier om die lelijke foutmelding te voorkomen, is het gebruik van een eigen exception handler. Net als met set_error_handler() kunnen we nu de functie set_error_handler() gebruiken:"

De 2e set_error_handler() moet set_exeption_handler() zijn
Dutch Caffeine
Dutch Caffeine
14 jaar geleden
 
0 +1 -0 -1
Mooie tutorial zeker.

Je lecht heel veel en heel goed uit wat wat is!

Super hoop op een volgende!

Mr. de Jong
Joren de Wit
Joren de Wit
14 jaar geleden
 
0 +1 -0 -1
@Robert Deiman: Tnx, aangepast :)
Citroen Anoniem Graag
Citroen Anoniem Graag
14 jaar geleden
 
0 +1 -0 -1
Zeer mooie tut, duidelijk, compleet, helder en goed te begrijpen. Dit is naar mijn mening 1 van de meest nuttige tuts die hop phphulp.nl staan.

Hulde!
Zero Dead
Zero Dead
14 jaar geleden
 
0 +1 -0 -1
Jammer. Goede tutorial, maar als je het mij vraagt slechte informatie. Des te meer informatie je een hacker geeft des te meer, maar vooral sneller, deze dingen op jou website kan uitvoeren.

Voorbeeld code:
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
ini_set('display_errors', 'On');
error_reporting(E_ALL);

$sql = "SELECT * FROM tabel";

if(!$res = mysql_query($sql))
{

    trigger_error(mysql_error().'<br />In query: '.$sql)
}

else
{
    // Rest van het script, fetchen van resultaten bijvoorbeeld.
}
?>


Nou vertel mij eens wat een willekeurige gebruiker aan deze informatie heeft? Niks! Dus waarom zou je het dan laten zien? De enige die er echt iets aan heeft is de hacker, welke dus nu al bijvoorbeeld de naam van je tabel weet. En natuurlijk die luie programmeur in zijn luie stoel die net geen extra stap wilt doen om een error te vinden.

Zet gewoon leuk in de htaccess error logging aan en display errors uit. Krijg je dan een error wordt dit mooi opgeslagen, en krijgt de gebruiker niets te zien. Deze heeft er toch niets aan. Het enige nadeel is dat de programmeeur bij het debuggen zijn error log de hele tijd moet openen en dat een gebruiker niet weet dat er een fout is. Nu zal de hacker toch moeten gaan gokken hoe je tabellen heten (bij de meeste databases is dit gewoon "users" en "admin"), en wanneer deze niet standaard zijn is dat alweer een beetje extra beveiliging. Ook als je bijvoorbeeld een keer bent vergeten ergens is_numeric op te doen en een hacker voert ?id=a in, dan krijgt die een leeg resultaat (of een index) zonder dat hij weet dat hij een error heeft getriggerd. Dan heb je dus weer minder kans dat hij doorgaat met een echte SQL injectie.

Verder ben ik niet de enige die het super stom vind als je display_errors op on hebt staan terwijl je website draait, kijk hier maar:
http://www.google.nl/search?hl=nl&q=display_errors&btnG=Google+zoeken&meta=
Robert Deiman
Robert Deiman
14 jaar geleden
 
0 +1 -0 -1
@Zerodead

Het gaat erom dat je error_reporting aan hebt staan als je een script maakt. Zo voorkom je (veelgemaakte) fouten, en bovendien scheelt het je zoekwerk. Daarnaast is het juist niet de bedoeling om deze complete foutmeldingen op je site weer te geven, maar kan je deze bijvoorbeeld simpel loggen in je eigen error_log. In plaats van de echte melding geef je dan een nette melding.
Elke fout, of je hem nu op je scherm weergeeft of niet, is er 1 te veel. Dus wel wegwerken de boel.

Je kan inderdaad error_logging aanzetten in je htacces, maar met een eigen error_handler heb je veel meer "vrijheid". Denk bijvoorbeeld aan het al of niet loggen van dezelfde error, maar op een ander tijdstip? Het gaat er juist om dat we heel veel vragen krijgen, over dingen die niet goed gaan waarvoor de error (mits error_reporting dus aanstaat in de "codeerfase") gewoon zichtbaar is.
Om dit te voorkomen is het werken met error_reporting op alles weergeven altijd handig. Vooral omdat je het meteen ziet als je test, en niet eerst een bestandje moet opzoeken en openen.
Joren de Wit
Joren de Wit
14 jaar geleden
 
0 +1 -0 -1
Zerodead, ik denk dat je deze tutorial nog maar eens heel goed en nauwkeurig door moet lezen!

Een heel belangrijk onderscheid dat jij in je hele verhaal vergeet te maken is het verschil tussen de ontwikkelfase, waarin het script gebouwd wordt, en de productiefase, waarin het script daadwerkelijk beschikbaar is voor het publiek. De situatie die jij als ideaal probeert te bestempelen is er een waarin een minimale vorm van foutafhandeling is toegepast die naar mijn mening in beide situaties niet voldoet!

Tijdens de ontwikkelfase ten eerste is er natuurlijk de overduidelijke reden dat je tijdens het debuggen de fouten gewoon op het scherm wilt zien en niet telkens in een log file op zoek moet naar een eventuele foutmelding. Daarnaast wil je dat tijdens de productiefase de gebruiker een nette foutmelding krijgt als er een fout opgetreden is. Natuurlijk ga je daarin geen gedetailleerde informatie geven, een melding als 'Sorry, op dit moment kan deze opdracht niet uitgevoerd worden, probeert u het later nog eens', voldoet. Vervolgens zou je de gedetailleerde foutmelding naar jezelf kunnen mailen of op kunnen slaan in een error log zodat je daar later naar kunt kijken.

Ik ben dan ook blij dat je dit voorbeeld hebt gekozen om kritiek op te geven, omdat dit voorbeeld nou precies illustreert hoe je op een mooie manier foutafhandeling kunt toepassen. Met de functie set_error_handler() waarmee je, zoals je op pagina 6 kunt lezen, een eigen foutafhandeling functie kunt gebruiken, kun je deze fout namelijk heel mooi afvangen en zelf bepalen wat je ermee doet. Afhankelijk van de fase waarin je site zich bevindt zou je ervoor kunnen kiezen om de foutmelding van de getriggerde fout domweg op het scherm te zetten ofwel om een nette foutmelding op het scherm te zetten en de gedetailleerde fout ergens op te slaan!

Verder zou ik je ook willen aanraden om het gedeelte over Exceptions nog eens heel goed te lezen. Deze manier van foutafhandeling biedt veel meer flexibiliteit dan je ooit in PHP gehad hebt en geeft dus ook veel meer mogelijkheden als het gaat om het geven van foutmeldingen, bijhouden van error logs, etc. Hiermee kun je in ieder geval een veel geavanceerdere foutafhandeling schrijven dan jouw htaccess error log, en de eindgebruiker hoeft geen enkele informatie op het scherm te zien!

Kortom, ik ben het helemaal niet eens met de beweringen die je doet. Een goede foutafhandeling is de basis van ieder goed script, en helaas valt enkel een simpele error log bij mij niet in de categorie 'goed'.

Als je nu gekomen was met het feit dat ik meer nadruk had kunnen leggen op het feit dat je op moet passen met het geven van gedetailleerde foutmeldingen tijdens de productiefase, dan had ik me daar in kunnen vinden (wellicht dat ik de tutorial op dat punt nog aan zal passen). Maar om nu te zeggen dat in deze tutorial slechte informatie staat, nee absoluut niet!
Zero Dead
Zero Dead
14 jaar geleden
 
0 +1 -0 -1
@Robert_Deiman,
Helaas werkt dit niet met fatal errors of syntax errors en worden deze dus gewoon genegeerd. Daarnaast, kan je volgens mij via htaccess ook nog isntellen dat die de errors die vaker voorkomen niet nogmaals in het error log zet. Ik noem het toch echt lui als je geen zin hebt om een bestandje te openen en de error te zoeken welke altijd onderaan wordt gedumpt.

Wat ik zelf doe is mijn error log regelmatig doorlezen en dan de errors die erin staan fixen en eruit gooien. Zoals ik al eerder melde, een gebruiker heeft niks aan een error, en de kans dat deze een mailtje schrijft is bijna nihil.

@Blanche, het gaat mij er eigenlijk om dat je voorbeelden fout zijn. De voorbeeld op pagina 6 is echt zo'n code die sommige gebruikers zullen copy-pasten en daar staat dus duidelijk in wat de error was en het pad naar het script.

Zelf ben ik pas op zoek geweest naar een mogelijkheid om alle errors met een mooie waarschuwing te laten weergeven, inclusief fatal en syntax errors. Dit is helaas niet mogelijk in PHP en dus heb ik gekozen om totaal niks te laten zien. Even de voor- en nadelen op een rijtje:
+ De "hacker" krijgt nooit (echt NOOIT) je pad te zien met bijvoorbeeld je FTP username
+ De gebruiker krijgt geen waardeloze "Parse error: syntax error, unexpected T_LNUMBER, expecting T_VARIABLE or '$' in blabla." - dit is net zoveel waard voor een "simpele" gebruiker als een lege pagina.
+ Geen notificatie voor een (potentiele) hacker dat er in een script een fout zit welke misbruikt kan worden.
- Lastiger met debuggen (luie programmeur die geen localhost maakt?)
- Minder gebruikers vriendelijk - ("Parse error: syntax error, unexpected T_LNUMBER, expecting T_VARIABLE or '$' in blabla." of een lege pagina...hmmm.)

Het opvangen van bijvoorbeeld een notice error zou nooit hoeven, want een goede programmeur die controleerd altijd of een waarde "isset". Dan kan je dus altijd een mooie error weergeven als "Voer aub een waarde in.".

Natuurlijk zet je bij het debuggen op een dev-server of localhost display_errors op "on", maar dit moet je nooit doen op je webserver.

Met mijn vorige antwoord wijs ik meer naar de voorbeelden die bij de tekst staan, deze hebben allemaal "trigger_error(mysql_error().'<br />In query: '.$sql)" of een andere echo welke gevoelige informatie kan weggeven. Nergens bij deze codes staat dat dit voorbeeld alleen bedoelt is voor tijdens de developing fase en niet tijdens het uitvoeren op de server.
Jacco Engel
Jacco Engel
14 jaar geleden
 
0 +1 -0 -1
Zerodead ,

ik noem jou nu al lui omdat je volgens mij gewoon geen zin heb om error_handling te schrijven op een manier zoals die in de ontwikkelfase toch soort van onmisbaar is.

En weer, iedereen praat hier over een ontwikkel omgeving terwijl jij het constant over de live omgeving hebt terwijl dit echt 2 hele verschillende dingen zijn.
Robert Deiman
Robert Deiman
14 jaar geleden
 
0 +1 -0 -1
@Zerodead

Ik vraag met met grote verbazing eigenlijk af welke fatal errors je zou moeten krijgen als je boel goed in mekaar zit, maargoed je zal daar wel een reden voor hebben om zo'n opmerking te maken.
Toch blijf ik erbij dat ik het prettig vind om met m'n eigen error handler te werken, omdat ik die bijvoorbeeld beschikbaar maak in mijn admin panel (+ andere sites die ik maak kan ik mijn errors rechtstreeks in m'n mail laten komen)

Quote:
Daarnaast, kan je volgens mij via htaccess ook nog isntellen dat die de errors die vaker voorkomen niet nogmaals in het error log zet. Ik noem het toch echt lui als je geen zin hebt om een bestandje te openen en de error te zoeken welke altijd onderaan wordt gedumpt.

Volgens jou kan het, maar ik wil daar graag bewijs voor zien. Bovendien ontvang ik graag een mailtje bij een fout (max 1x per dag of per week!)

Wat jij zegt van de pars error: Die krijgt je gebruiker ook niet, zoals blanche al aangeeft: Of je script is goed en je krijgt niet zo'n syntax error (je werkt fouten weg met je error_handling aan weet je nog?) Notificaties worden dan ook weergegeven, dus heb je ook weg moeten werken.

Quote:
De "hacker" krijgt nooit (echt NOOIT) je pad te zien met bijvoorbeeld je FTP username

Wederom: Als jij je fouten wegwerkt, en foutafhandeling op een goede manier gebruikt, komt dit ook NOOIT voor. Bovendien staan je FTP gegevens in een PHP file, en alleen in variabelen. Daarbuiten worden die gegevens gebruikt. Het pad naar die Connection file is beveiligd en alleen toegankelijk via een PHP script. (mits je dat goed aanpakt!) Dus komt dat ook nooit voor.

Het enige voor argument wat ik zo zou kunnen bedenken is dat je geen ingewikkelde error_handler() moet maken.


Edit:

@Jacco
Quote:
En weer, iedereen praat hier over een ontwikkel omgeving terwijl jij het constant over de ontwikkelomgeving terwijl dit echt 2 hele verschillende dingen zijn.

Ik denk dat je het over de ontwikkelomgeving en de "online omgeving" hebt? :)
Jacco Engel
Jacco Engel
14 jaar geleden
 
0 +1 -0 -1
Robert u get the punt
- wes  -
- wes -
14 jaar geleden
 
0 +1 -0 -1
Zerodead, er is een groot verschil in errorlogging voor ontwikkelaars en voor gebruikers, jij haalt deze door elkaar.

En je bent idd lui as previously stated
Joren de Wit
Joren de Wit
14 jaar geleden
 
0 +1 -0 -1
Zerodead, ik vraag me af of je mijn reactie ?berhaupt wel gelezen hebt. Volgens mij leg ik daarin toch duidelijk het verschil tussen de ontwikkel en productie omgeving uit en hoe je daarbij verschillende vormen van foutafhandeling kunt gebruiken.

Quote:
Met mijn vorige antwoord wijs ik meer naar de voorbeelden die bij de tekst staan, deze hebben allemaal "trigger_error(mysql_error().'<br />In query: '.$sql)" of een andere echo welke gevoelige informatie kan weggeven.
Wat je hier zegt klopt niet. Een trigger_error() is absoluut niet gelijk aan een echo! Met deze functie trigger je namelijk een error handler om de fout af te handelen. Het mooie is dat je hier je eigen error handler voor kunt gebruiken die de foutmelding verwerkt, de foutmelding hoeft dus niet per se op het scherm te komen! Als ik een eigen error handler definieer, zou ik deze fouten ook heel goed naar mezelf kunnen mailen of in een error log kunnen opslaan terwijl ik de gebruiker een nette foutmelding geef.

En het mooiste is daarbij nog, dat alle syntax en fatal errors ??k door deze error handler worden opgevangen! Dus ook daarvan krijgt de gebruiker niets meer op het scherm te zien! Ik heb er overigens iets over het verschil tussen ontwikkelfase en productiefase toegevoegd aan de tutorial.

Tenslotte hoor ik je helemaal nergens over het gebruik van Exceptions? Heb je er nog nooit naar gekeken of vind je dat ook een waardeloze manier van foutafhandeling?
Jacco Engel
Jacco Engel
14 jaar geleden
 
0 +1 -0 -1
Volgens mij vind hij foutafhandeling zowiezo een waardeloze manier van programeren :P
Joren de Wit
Joren de Wit
14 jaar geleden
 
0 +1 -0 -1
Jacco:
Volgens mij vind hij foutafhandeling zowiezo een waardeloze manier van programeren :P
Tja, hij heeft opzich wel een goed punt als je zegt dat je in een productieomgeving geen gedetailleerde fouten op het scherm moet zetten. Maar het lijkt wel alsof hij niet in wil zien dat er ook een andere oplossing is dan het compleet uitschakelen van de foutafhandeling en enkel een zielig simpel error logje bij te houden.
Robert Deiman
Robert Deiman
14 jaar geleden
 
0 +1 -0 -1
@Blanche

Maar dat stond ook al duidelijk in mijn reactie, waarin ik al aangaf wat het verschil was/ is tussen beide omgevingen. De gebruiker krijgt een nette melding als: "Er is een fout opgetreden bij het ophalen van de informatie. De beheerder is hierover ingelicht, probeert u het later nog eens."

Daar kan niemand gevoelige informatie uit halen, terwijl je wel voor een goede voorlichting voor je bezoekers zorgt.

@Zerodead

Het Grootste nadeel van jou manier is dat je geen fouten meer weergeeft, maar als je dus een fout krijgt werkt er iets niet. Jij kan dat wel zien, maar jou bezoeker niet. Denk je dat een bezoeker nog terugkomt als hij het gevoel heeft dat iets niet in de haak is (Hij vraagt informatie op, maar ziet niets en krijgt ook geen melding) en hij daarover geen melding krijgt?
De bezoeker moet je behandelen alsof hij in een winkel is: Klopt er iets niet, geef dan op zijn minst aan DAT er iets niet klopt, en dat het genoteerd is. Dat geeft de bezoeker in ieder geval het gevoel dat er iets mee gedaan wordt (/gaat worden)
Zero Dead
Zero Dead
14 jaar geleden
 
0 +1 -0 -1
@Jacco, ik heb een tijd terug al een perfecte error handler geschreven welke de errors logt, tijdstip, IP, browser, pad etc. Ik vond het alleen te zonde dat parse errors niet worden opgevangen dat ik toch maar voor een andere optie heb gezocht.

@Robert, met de waarde ignore_repeated_source kan je instellen om herhalende errors niet in het logboek te zetten.

Dat mail scriptje is niet al te moeilijk op te bouwen, je maakt een cron job aan, zorgt dat een PHP script eens in het uur/dagkijkt of de grootte van het log-bestand even groot is als de vorige keer en zo niet, dan stuur je een waarschuwing naar een email met bijvoorbeeld de laaste (5) error(s).

Op een behoorlijk aantal servers, waaronder de mijne, staat DirectAdmin ge?nstalleerd. Als je dan een pad te zien krijgt weet je gelijk wat de naam van FTP is.
Voorbeeldje:
Quote:
Regelnummer: 8
Bestand: /Users/jorendewit/Sites/jorendewit/phphulp/pdo.php
Foutmelding: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.bestaat_niet' doesn't exist


Nu is 9 van de 10 keer "jorendewit" de gebruikersnaam.

@Blanche,
Quote:
Wat je hier zegt klopt niet. Een trigger_error() is absoluut niet gelijk aan een echo! Met deze functie trigger je namelijk een error handler om de fout af te handelen. Het mooie is dat je hier je eigen error handler voor kunt gebruiken die de foutmelding verwerkt, de foutmelding hoeft dus niet per se op het scherm te komen!


Maar dan heb je later dus weer die error_handler van jou, welke een aantal mensen dus gewoon zullen copy-pasten, en dit terug gooit: "echo 'Foutmelding: '.$sMessage.'<br />';".

Quote:
En het mooiste is daarbij nog, dat alle syntax en fatal errors ??k door deze error handler worden opgevangen! Dus ook daarvan krijgt de gebruiker niets meer op het scherm te zien!


Volgens mij niet. Deze errors die komen te voorschijn voordat ook maar eits uit het script is geladen, inclusief de error-handler. Ik heb zelf ge?xperiementeerd met een auto_prepend_file, maar deze ving ook niet alles op wat ik wilde.

Quote:
Tenslotte hoor ik je helemaal nergens over het gebruik van Exceptions? Heb je er nog nooit naar gekeken of vind je dat ook een waardeloze manier van foutafhandeling?


Ik heb me hier nog niet in verdiept, nee. Maar, ik ben zelf gewend om gewoon gelijk de waardes te controleren, bijvoorbeeld;
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

if(isset($_GET['id']) AND is_numeric($_GET['id'])) {
    // Open bijvoorbeeld het artikel
} else {
    if(isset($_GET['id']) AND !is_numeric($_GET['id']))
        echo "Vul aub een nummer in als id.";
    else {
        // laat index zien of niets
    }
}


?>


Wat jij nu wilt doen, is gelijk deze error loggen etc etc. (let wel op, deze error is slechts als voorbeeld, ik neem aan dat je bij zo'n simpele fout niet een error handler gebruikt).

@Jacoo weer, nee. Ik vind een foutafhandeling juist zeer goed, maar dan moet die wel elke fout op kunnen vangen, en zolang dat niet gebeurt heb je er niet al te veel aan.

@Robert, daar heb je gelijk in, maar zolang dit niet mogelijk is icm. parse errors heb ik toch de voorkeur aan geen errors at all.

Tot slot, het enige wat ik graag aan verandering zou zien in je tutorial is dat je bij de scripts als comment zet dat je een bepaalde error beter kan aanpassen als je een script aan het draaien bent.

Bijvoorbeeld op pagina 6, het 4e code blok, als je hier bij dat echo-blok zet dat je de foutsoort, -melding, bestand en regel het beste niet kan laten zien in de productie fase (met een reden), dan zullen mensen hier sneller naar kijken en hat aanpassen dan zonder deze opmerking.
Robert Deiman
Robert Deiman
14 jaar geleden
 
0 +1 -0 -1
Zeg dan dat je dat wil zien, en niet dat dit geen goede manier van error handling is. Al die errors die jij noemde zijn gewoon te ondervangen en kan je met trigger_error() gewoon weergeven.
Waarom zouden parse errors niet opgevangen worden ondervangen:

Klik Daar staat keurig bij dat ook parse errors worden weergegeven bij E_ALL, als ze worden weergegeven kan je ze ook loggen zou je zeggen, niet?

Je boort nu een heel goed voorbeeld van hoe mensen eigenlijk te werk zouden moeten gaan helemaal de grond in. Jij wil weer terug naar vroeger, waar je niets met errors deed en ontwikkelen van een website veel werk koste, omdat je errors niet goed kon vinden.

Jou voorbeeld is wederom ook 1 die je kan ondervangen:
Regelnummer: 8
Bestand: /Users/jorendewit/Sites/jorendewit/phphulp/pdo.php
Foutmelding: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.bestaat_niet' doesn't exist
Dit geef je dus NIET zo aan users weer.
Joren de Wit
Joren de Wit
14 jaar geleden
 
0 +1 -0 -1
Zerodead:
Volgens mij niet. Deze errors die komen te voorschijn voordat ook maar eits uit het script is geladen, inclusief de error-handler.
Hier heb je inderdaad gelijk in, deze zullen niet afgevangen worden door een custom error handler. Maar daarnaast komen dit soort fatale fouten als het goed is alleen voor tijdens de ontwikkelfase en wil je natuurlijk dat deze op het scherm getoond worden. Als deze fouten optreden in de productiefase, gaat het eerder al ergens fout...

Zerodead:
Wat jij nu wilt doen, is gelijk deze error loggen etc etc. (let wel op, deze error is slechts als voorbeeld, ik neem aan dat je bij zo'n simpele fout niet een error handler gebruikt).
Uiteraard vang ik deze fouten niet af met een error handler. Deze meldingen sla je gewoon op in bijvoorbeeld een array $aErrors en geef je ze weer op het moment dat dat nodig is. De error handler gebruik je pas zodra je belangrijkere foutmeldingen hebt, zoals bijvoorbeeld sql errors. In al die gevallen gebruik je trigger_error() of werp een je een nieuwe Exception...

Zerodead:
... welke een aantal mensen dus gewoon zullen copy-pasten
Een tutorial is er om als voorbeeld te dienen, niet om alles klakkeloos te kopieren. De voorbeelden die ik geef zijn dan ook enkel voorbeelden om te laten zien hoe je het aan zou kunnen pakken. Ik vermeld er dan ook niet voor niets het volgende bij:
Quote:
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.

Als mensen toch enkel de voorbeelden kopieren en niet mijn commentaar erbij lezen, dan zal de foutafhandeling niet het eerste zijn dat problemen oplevert. In dat geval zullen er waarschijnlijk veel grotere beveiligingslekken in hun scripts zitten, die veel meer gevaar opleveren dan een gedetailleerde foutmelding op het scherm.

Quote:
Tot slot, het enige wat ik graag aan verandering zou zien in je tutorial is dat je bij de scripts als comment zet dat je een bepaalde error beter kan aanpassen als je een script aan het draaien bent.
Kijk dat is al een hele andere opmerking dan je in eerste instantie maakte. Die heb ik ook zeker al ter harte genomen en de tutorial een paar punten aangepast.
Frank -
Frank -
14 jaar geleden
 
0 +1 -0 -1
@Zerodead: Foutafhandeling wil niet zeggen dat je interne foutmelding in een productie-omgeving op het scherm presenteert. Tijdens de diverse fases van een systeem (bouw/test/productie) laat je de foutafhandeling verschillende taken uitvoeren.

Bouwfase: Zet alle fouten en notices overzichtelijk op het scherm
Testfase: Zet alle fouten en notices in een logboek en een gebruikersvriendelijke melding op het scherm
Productiefase: Zet uitsluitend gebruikersvriendelijke meldingen op het scherm, zet de melding van de server in het logboek en stuur een email naar de beheerder.

Dat zijn 3 totaal verschillende zaken, totaal verschillende instellingen.

Jammer dat je de tutorial zo afkraakt, het is een waardevolle aanvulling, zeker voor de beginnende php-ers die hier in grote aantallen rondlopen. Iedere vorm van foutafhandeling is beter dan geen foutafhandeling, zelfs dat veiligheidsrisico's met zich meebrengt, het begin is er.
Evoken
Evoken
14 jaar geleden
 
0 +1 -0 -1
Hmm ik blijft maar een totaal wit scherm krijgen als ik expres een foutje maak en deze wil weergeven..
Joren de Wit
Joren de Wit
14 jaar geleden
 
0 +1 -0 -1
Test je dit bij een host of lokaal? In het laatste geval zou je eens in je php.ini kunnen controleren of de 'display_errors' setting wel op 'on' staat.

Anders zou je met een .htaccess in de root met daarin de volgende regels, deze instelling ook aan kunnen proberen te zetten:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
php_flag display_errors on


Je stelt het weliswaar met ini_set() ook in je php scripts in, maar deze functie wordt pas uitgevoerd als er geen parse errors in je script zitten. Je kunt hem dus niet gebruiken om te zorgen dat parse errors weergegeven worden.
Michael
michael
14 jaar geleden
 
0 +1 -0 -1
wow heel netjes gedaan! dikke 10 inderdaad! bedankt! zeker wat geleerd
Christiaan Baartse
Christiaan Baartse
14 jaar geleden
 
0 +1 -0 -1
Op pagina 9 is onderstaande natuurlijk netter

Voor de rest duidelijk!

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
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);

class Gebruiker
{
    const NAME_ERROR = 1;
    const AGE_ERROR = 2;
    const AVATAR_ERROR = 4;
    
    protected $sGebruikersnaam;
    protected $iLeeftijd;
    protected $sAvatar;
    protected $sDir = 'avatars/';
    
    function
__construct($sGebruikersnaam, $iLeeftijd, $sAvatar)
    {

        if(strlen($sGebruikersnaam) < 3)
        {

            throw new Exception('Aanmaken instantie van "'.__CLASS__.'" mislukt.', self::NAME_ERROR);
        }

        if(!is_numeric($iLeeftijd))
        {

            throw new Exception('Aanmaken instantie van "'.__CLASS__.'" mislukt.', self::AGE_ERROR);
        }

        if(!file_exists($this->sDir.$sAvatar))
        {

            throw new Exception('Aanmaken instantie van "'.__CLASS__.'" mislukt.', self::AVATAR_ERROR);
        }

        
        $this->sGebruikersnaam = $sGebruikersnaam;
        $this->iLeeftijd = $iLeeftijd;
        $this->sAvatar = $sAvatar;
    }
}


try
{
    $gebruiker = new Gebruiker('Henk', 25, 'plaatje.png');
}

catch(Exception $e)
{

    echo 'Error: '.$e->getMessage().'<br />';
    echo 'File: '.$e->getFile().'<br />';
    echo 'Line: '.$e->getLine().'<br />';
    
    if($e->getCode() == Gebruiker::NAME_ERROR)
    {

        echo 'Details: De minimale lengte van een gebruikersnaam is 3 tekens.<br />';
    }

    elseif($e->getCode() == Gebruiker::AGE_ERROR)
    {

        echo 'Details: De opgegeven leeftijd is geen integer.<br />';
    }

    elseif($e->getCode() == Gebruiker::AVATAR_ERROR)
    {

        echo 'Details: Het opgegeven bestand bestaat niet. De uitvoer van het script wordt gestopt...';
        exit();
    }
}

?>
Frank -
Frank -
14 jaar geleden
 
0 +1 -0 -1
@Christiaan: Leg eens uit, nu moeten we zelf gaan raden wat jouw argumenten zijn. En dat kunnen hele goede argumenten zijn!

Graag even verduidelijken.
Tom K
Tom K
14 jaar geleden
 
0 +1 -0 -1
wat een goede tutorial, zorgt ervoor dat m'n foutafhandeling een stuk mooier wordt. Bedankt!
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Christiaan Baartse
Christiaan Baartse
14 jaar geleden
 
0 +1 -0 -1
@pgFrank: Leesbaarheid uber alles.
Ipv 1 heb ik dus de constante Gebruiker::NAME_ERROR gebruikt, zodat je ziet dat het om de NAME_ERROR gaat.

Als je deze constantes toch al gebruikt om ze aan te maken, waarom dan ook niet om ze weer te checken?

(mn aardappeltjes bakte aan dus ik had haast :P)

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

 
 

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.