In eerdere hoofdstukken kon een fout je hele script laten crashen. Met try-catch kun je fouten opvangen en netjes afhandelen. Je plaatst riskante code in een try-blok en vangt fouten op in een catch-blok.
<?php
try {
$resultaat = 10 / 0;
} catch (DivisionByZeroError $e) {
echo "Fout: " . $e->getMessage();
}
?>
PHP kent twee soorten problemen:
TypeError, DivisionByZeroError, ParseErrorException, InvalidArgumentException, RuntimeExceptionBeide kun je opvangen met catch.
Let op: In de oefeningen hieronder hoef je GEEN <?php en ?> tags te typen. Het platform regelt dit automatisch. Je typt alleen de PHP-code zelf.
Schrijf een try-catch blok dat intdiv(10, 0) probeert uit te voeren. Vang de DivisionByZeroError op en toon "Delen door nul is niet toegestaan".
Schrijf een try-catch blok. In het try-blok: maak een variabele $json met de waarde "geen json" en decodeer deze met json_decode($json, true, 512, JSON_THROW_ON_ERROR). Vang de Exception op en toon het foutbericht met $e->getMessage().
Schrijf een try-catch blok. In het try-blok: probeer een niet-bestaand bestand te openen met $inhoud = file_get_contents("geheim.txt"). Als $inhoud gelijk is aan false, gooi dan zelf een exception met throw new Exception("Bestand niet gevonden"). Vang de exception op en toon het bericht.
Schrijf een functie deel($a, $b) die $a / $b berekent. Als $b gelijk is aan 0, gooi dan een Exception met het bericht "Deler mag niet nul zijn". Roep de functie aan in een try-catch met deel(10, 0) en toon het foutbericht.
Je kunt meerdere catch-blokken gebruiken om verschillende soorten fouten apart af te handelen. Je kunt ook eigen exception-klassen maken door Exception uit te breiden.
<?php
class LeeftijdException extends Exception {}
function controleerLeeftijd($leeftijd) {
if ($leeftijd < 0) {
throw new LeeftijdException("Leeftijd kan niet negatief zijn");
}
if ($leeftijd > 150) {
throw new LeeftijdException("Onrealistische leeftijd");
}
return "Leeftijd: " . $leeftijd;
}
?>
Schrijf twee catch-blokken. In het try-blok: probeer intdiv("tekst", 2) uit te voeren. Vang eerst TypeError op met het bericht "Typefout opgetreden" en daarna Exception als vangnet met "Onbekende fout".
Maak een eigen exception-klasse ValidatieException die Exception uitbreidt. Schrijf een functie valideerEmail($email) die controleert of het @-teken voorkomt met strpos(). Zo nee, gooi een ValidatieException met "Ongeldig e-mailadres". Test met valideerEmail("geenmail") in een try-catch en toon het foutbericht.
Schrijf een functie valideerLeeftijd($leeftijd) die een Exception gooit als de leeftijd kleiner is dan 0 (bericht: "Te jong") of groter dan 150 (bericht: "Onrealistisch"). Return anders "Geldig: " gevolgd door de leeftijd. Test met valideerLeeftijd(-5) in een try-catch.
Schrijf een functie berekenKorting($prijs, $percentage) die een Exception gooit als de prijs negatief is (bericht: "Prijs moet positief zijn") of als het percentage niet tussen 0 en 100 ligt (bericht: "Percentage moet tussen 0 en 100 liggen"). Return anders de korting ($prijs * $percentage / 100). Test met berekenKorting(100, 150) in een try-catch.
Het finally-blok wordt altijd uitgevoerd, ongeacht of er een fout optrad of niet. Dit is handig voor opruimacties zoals het sluiten van bestanden of databaseverbindingen.
<?php
try {
$bestand = fopen("data.txt", "r");
// Werk met bestand...
} catch (Exception $e) {
echo "Fout: " . $e->getMessage();
} finally {
echo "Opruimen voltooid";
}
?>
Schrijf een try-catch-finally blok. In het try-blok: gooi een Exception met "Iets ging mis". In catch: toon het foutbericht. In finally: toon " | Altijd uitgevoerd".
Schrijf een functie veiligDelen($a, $b) die try-catch-finally gebruikt. In try: als $b nul is, gooi een Exception. Anders return het resultaat. In catch: return 0. In finally: (doe niets extra). Test met echo veiligDelen(10, 0) en daarna echo " | " en echo veiligDelen(10, 2).
Bouw een compleet validatiesysteem. Maak een eigen exception InvoerException die Exception uitbreidt. Schrijf een functie valideerInvoer($waarde) die een InvoerException gooit als de waarde leeg is (bericht: "Invoer mag niet leeg zijn") of als de waarde langer is dan 50 tekens (bericht: "Invoer te lang"). Gebruik try-catch-finally. Test met een lege string. In finally: toon " [Validatie afgerond]".
try-catch om fouten netjes op te vangen zonder dat je script crashtthrow new Exception("bericht")catch-blokken voor verschillende fouttypen (meest specifieke eerst)class MijnException extends Exception {}finally-blok wordt altijd uitgevoerd, ook als er een fout optrad$e->getMessage() om het foutbericht op te halen