try... catch en @
Pagina: « vorige 1 2 3 volgende »
Je krijgt een view te zien met het veld om te reageren, je typt hier een paar dingen in en je submit.
Je gaat nu controleren op een veld (bijvoorbeeld dat je nog een captcha moet invullen)
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
try{
validate(captcha);
showTopic();
}catch(Exception $e){
//iets fout gegaan dus foutmelding +
showTopicReactForm($e->getMessage);
}
?>
try{
validate(captcha);
showTopic();
}catch(Exception $e){
//iets fout gegaan dus foutmelding +
showTopicReactForm($e->getMessage);
}
?>
Het is maar een voorbeeld wat misschien zou kunnen, maar ik weet ook niet echt hoe je het goed kan toepassen in MVC.
Ah, oké... ik dacht dat je een soort validate functie bedoelde die alleen een foutmelding echoode, maar in de bovengenoemde opzet moet je telkens allerlei specifieke try en catch blokken maken.
Niet als je 1 form validator hebt die de afhandeling voor je hele formulier doet en daaruit een exception opbrengt als het niet goed is.
Nou, dat bedoelde ik dus... maar in mijn voorbeeldje... hoe komt ie dan weer terug bij toView() en showView()?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
try{
$formvalidator->validate('form1'); //formulier validaten, dus $_POST['form1_name'] etc
//geen exception dus het is gelukt
showView('topic.php');
}catch(InvalidFormException $e){
toView($e->getMessage);
showView('topic_react.php');
}
//je zou ook nog hier iets kunnen doen als je dat wilt
?>
try{
$formvalidator->validate('form1'); //formulier validaten, dus $_POST['form1_name'] etc
//geen exception dus het is gelukt
showView('topic.php');
}catch(InvalidFormException $e){
toView($e->getMessage);
showView('topic_react.php');
}
//je zou ook nog hier iets kunnen doen als je dat wilt
?>
Op die manier kun je toch mooi de juiste view weergeven?
Gewijzigd op 16/01/2012 12:25:29 door Jelle -
Ja oké... maar stel nu dat je dus slechts één groot try-catch blok hebt, wat dan? Dus de complete code van je website staat in 1 try blok, dan kun je die catch niet specifiek maken en dan kun je dus ook geen specifieke view (topic_react.php) aanroepen. Snap je wat ik bedoel?
Scheiding tussen je technische en user-gerelateerde fouten, bij een sql fout kun je er vanuit gaan dat de pagina's er toch niet goed uit komen dus laat je een fout specifeiek pagina zien. Maar bij user gerelateerde fouten vang je die dus dichter bij de fout op (en niet helemaal in het grote overkoepelende try catch blok).
Je kunt honderden try catch blokken in elkaar hebben staan, als de eerste hem niet pakt, probeert de gene daarboven dit wel etc...
Hmmm, oké... maar wat is dan het voordeel om het via try-catch te doen ipv if-else? (op dit lagere niveau bedoel ik dan he)
Als je veel met objecten werkt en deze dingen laat valideren kunnen exceptions wellicht handiger zijn, in principe is er niet een "betere" keus het is meer een keuze wat de "mooiere" oplossing is.
Hmmm, oké... ik zal er eens over nadenken. Ben in ieder geval weer wat wijzer :)
try {
// hele website
} catch ( Exception $e) {}
Bij de eerste catch stopt de rest van je script namelijk compleet. Als die op de allereerste regel al een exception pakt, stopt de hele site tot er een catch blok gevonden wordt.
Code (php)
Wat je over het algemeen doet trouwens is de try-catch-finally. De finally wordt hoe dan ook uitgevoerd dus er moet verder nergens website logica staan in catch blokken. Helaas voor PHP gebruikers is er geen finally die uitgevoerd wordt, wat ook logisch is gezien het feit dat PHP een script taal is. M.a.w. alles na de catch wordt toch proc. uitgevoerd.
Het is slim om alle specifieke exceptions apart af te vangen. Als je een object creert kun je dat het beste wrappen om een try-catch blok. Op die manier vang je alle exceptions die door dat object gegooid kunnen worden. Wat ook helpt is onder elke class een <class>Exception te zetten en die exceptions te gooien in je bron class.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class Application {
// je logic voor deze class of zo
}
class ApplicationException extends Exception {
// origineel heeft een exception 3 params, $message, $line en $previous
// maar voor dit voorbeeldje maakt het niet echt uit of wel :)
public function __construct($message){
parent::__construct($message);
}
}
?>
class Application {
// je logic voor deze class of zo
}
class ApplicationException extends Exception {
// origineel heeft een exception 3 params, $message, $line en $previous
// maar voor dit voorbeeldje maakt het niet echt uit of wel :)
public function __construct($message){
parent::__construct($message);
}
}
?>
Gewijzigd op 16/01/2012 15:54:42 door Pieter Jansen
Merijn, dankjewel voor je toelichting... maar de heren hiervoor zeggen dat je wel je hele website in een try-catch kan zetten. Nu weet ik het niet meer :-s
Volgens mij is het net gewoon wat het makkelijkste uit komt, en is beiden niet verkeerd?
Gewijzigd op 16/01/2012 16:32:37 door - Ariën -
Volgens mij wil je ook dat je script stopt met uitvoeren op het moment dat er een DB fout optreedt. Die handel je af (log/mail) en dan toon je een foutpagina die niet db afhankelijk is.
Het hele idee van exceptions is dat je dat als je standaard debug tool gebruikt. Als er een CriticalDatabaseException gegooid wordt en die catch je, kun je stoppen met je website script, maar als er een NoResultException gegooid wordt, ga je door.
Een try catch op je hele website is erg slecht om de volgende reden:
De allereerste exception die gevonden wordt zorgt ervoor dat je hele website stopt met functioneren. Dat kan nooit de bedoeling zijn, kijk eens naar error_reporting, daar stopt het script ook pas als er een fatal error plaats vindt. Een notice of mysql_error killt je site niet.
Daarom is de regel dus dat je alles wat errors gaan gooien, je die ook specifiek daar afhandelt. try catch is niet een easy way out of error reporting om het maar zo te noemen.
Bedoel je dat er geen resultaten gevonden worden? Maar dat zou toch gewoon kunnen als het betreffende resultaat niet in de database voorkomt? Moet je daar dan een exception voor throwen?
Een try catch om je hele code wrappen is wel mogelijk, maar niet raadzaam, zoals met alles ligt het aan scope. Je kunt try catch blokken ook nesten binnen een try, dan wordt het geneste try blok eerst doorlopen en eventuele exceptions in de geneste catch gevangen. De root try catch pakt dan alle onafgehandelde exceptions op en killt nog steeds je app als je niet oplet.
Het nadeel van de globale manier is dat je totaal niet weet waar iets mis gaat, dus loggen en debuggen heeft geen zin op die manier, dan kun je net zo goed niet met exceptions gaan werken.
Waarom niet? Je kunt toch nog steeds de exception gegevens opvragen?
Mijn idee is: zorg dat je weet welk wapen je tegen welke vijand gebruikt.
Nu; ik ben een C/c++/C# mens. misschien wordt try/catch in andere talen wel gemakkelijker gebruikt over een hele applicatie. In dat geval ... doe vooral waar je je gemakkelijk mee voelt.
Kijk ook eens hier:
http://www.phphulp.nl/php/tutorial/data-verwerking/foutafhandeling-in-php-error-handling/571/
Deze tutorial toont je hoe je fouten opvangt die normaal gezien op het scherm zouden worden getoond.
@Kris, ik heb mijn achtergrond in Java en daar werkt het voortreffelijk, het is de meest gebruikte manier van foutafhandeling en daar wordt het heel anders gebruikt in PHP. Maar ook in Java ( net als in C# etc) wordt het niet over een hele applicatie gebruikt. Bovendien is je entrypoint van belang.
Dus kies je voor exceptions, dan hoor je het goed te gaan gebruiken. niets zo vervelend als bijvoorbeeld:
try {
// code
} catch {}
of
try {
// er wordt een StreamNotFoundException gegooid
} catch (Exception e){
e.getMessage();
}
in beide gevallen sla je de plank mis. En de laatste is niet zo erg, mits je de gewone exceptions als fallback hanteert, dus:
catch ( StreamNotFoundException e){ /* handel je code af */ }
catch ( FileNotFoundException e) { /* handel je code af */ }
catch ( Exception e){ /* handel je code af */ }