PHP Exception Handling

Kursaanbeveling:

Een uitzondering (Exception) wordt gebruikt om de normale stroom van het script te wijzigen wanneer een specifieke fout optreedt.

Wat is een uitzondering?

PHP 5 biedt een nieuwe objectgeoriënteerde foutbehandelmethode.

Uitzonderingsbehandeling wordt gebruikt om de normale stroom van het script te wijzigen wanneer een specifieke fout (uitzondering) optreedt. Dit wordt een uitzondering genoemd.

  • Wanneer een uitzondering wordt getriggerd, gebeurt meestal:
  • De huidige codestatus wordt opgeslagen
  • Afhankelijk van de situatie kan de processor mogelijk de code opnieuw uitvoeren vanaf de opgeslagen codestatus, de scriptuitvoering beëindigen of de scriptuitvoering voortzetten vanaf een andere locatie in de code

We zullen verschillende foutbehandelmethode tonen:

  • Basisklant van uitzonderingen
  • Maak een aangepaste uitzonderingsprocessor
  • Meerdere uitzonderingen
  • Herhalen van de uitzondering
  • Top-level uitzonderingsprocessor instellen

Basisklant van uitzonderingen

Wanneer een uitzondering wordt gegooid, wordt de code daarna niet voortgezet, PHP zal proberen een matchend "catch"-blok te vinden.

Als een uitzondering niet wordt opgevangen en er is geen set_exception_handler() gebruikt voor de juiste behandeling, dan zal een ernstige fout (fatale fout) optreden en het foutbericht "Uncaught Exception" (ongevangen uitzondering) worden weergegeven.

Laten we proberen een uitzondering te gooien, maar niet te vangen:

<?php
//maak een functie met een uitzondering
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Waarde moet 1 of lager zijn");
  }
 return true;
 }
//trigger exception
checkNum(2);
?>

Het bovenstaande code zal een fout krijgen zoals dit:

Fatale fout: Ongevangen uitzondering 'Exception' 
met het bericht 'Waarde moet 1 of lager zijn' in C:\webfolder\test.php:6 
Stack trace: #0 C:\webfolder\test.php(12): 
checkNum(28) #1 {main} gegooid in C:\webfolder\test.php op regel 6

Try, throw en catch

Om de fouten uit het vorige voorbeeld te vermijden, moeten we geschikte code schrijven om uitzonderingen te verwerken.

Een juiste handler zou moeten omvatten:

  1. Probeer - Functies die uitzonderingen kunnen veroorzaken moeten zich bevinden binnen een "try"-blok. Als er geen uitzondering wordt getriggerd, wordt de code gewoon voortgezet. Maar als een uitzondering wordt getriggerd, wordt een uitzondering gegooid.
  2. Throw - Hier wordt bepaald hoe een uitzondering wordt getriggerd. Elk "throw" moet minimaal één "catch" hebben
  3. Catch - De "catch" codeblok vangt de uitzondering op en maakt een object aan dat de uitzonderingsinformatie bevat

Laten we een uitzondering triggeren:

<?php
//Maak een functie die een uitzondering kan gooien
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Waarde moet 1 of lager zijn");
  }
 return true;
 }
//Trigger een uitzondering in de "try" codeblok
try
 {
 checkNum(2);
 //Als de uitzondering wordt gegooid, wordt deze tekst niet weergegeven
 echo 'Als je dit ziet, is het getal 1 of lager';
 }
//CATCH uitzondering
catch(Exception $e)
 {
 echo 'Bericht: ' . $e->getMessage();
 }
?>

Het bovenstaande code geeft een foutmelding zoals deze:

Bericht: Waarde moet 1 of lager zijn

Example explanation:

Het bovenstaande code gooit een uitzondering en vangt deze op:

  1. Maak de checkNum() functie. Deze controleert of het getal groter is dan 1. Als dat zo is, gooit hij een uitzondering.
  2. De checkNum() functie wordt aangeroepen in de "try" codeblok.
  3. De uitzondering in de checkNum() functie wordt gegooid
  4. "Catch" codeblok ontvangt deze uitzondering en maakt een object aan dat de uitzonderingsinformatie bevat ($e).
  5. Door $e->getMessage() van dit exception object aan te roepen, wordt de foutmelding van de uitzondering weergegeven

Om te voldoen aan het principe van “elke throw moet een catch hebben”, kunt u een top-level exception handler instellen om gemiste fouten te verwerken.

Maak een aangepaste Exception klasse

Het maken van een aangepaste exception handler is zeer eenvoudig. We maken eenvoudig een speciale klasse die kan worden aangeroepen wanneer er een uitzondering optreedt in PHP. Deze klasse moet een extensie zijn van de exception klasse.

Deze aangepaste exception klasse erfde alle eigenschappen van de PHP exception klasse, u kunt er aangepaste functies aan toevoegen.

We beginnen met het creëren van een exception klasse:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = 'Fout op regel '.$this->getLine().' in '.$this->getFile()
  : <b>'.$this->getMessage().'</b> is geen geldig e-mailadres
  return $errorMsg;
  }
 }
$email = "iemand@example...com";
try
 {
 //Controleer of 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

Deze nieuwe klasse is een kopie van de oude exception-klasse, plus de errorMessage() functie. Omdat het een kopie van de oude klasse is, erfde het de eigenschappen en methoden van de oude klasse, zodat we de methoden van de exception-klasse kunnen gebruiken, zoals getLine(), getFile() en getMessage().

Example explanation:

Het bovenstaande codevoorbeeld gooit een uitzondering en vangt deze op met een aangepaste exception-klasse:

  1. The customException() class is created as an extension of the old exception class. This way, it inherits all properties and methods of the old class.
  2. Maak de errorMessage() functie. Als het e-mailadres ongeldig is, retourneert deze functie een foutmelding
  3. Stel de variabele $email in op een ongeldig e-mailadresstring
  4. Het uitvoeren van het "try"-blok, vanwege een ongeldig e-mailadres, gooit een uitzondering
  5. Een "catch"-blok vangt de uitzondering op en toont de foutmelding

Meerdere uitzonderingen

U kunt meerdere uitzonderingen gebruiken voor een script om verschillende situaties te detecteren.

U kunt meerdere if..else-blokken gebruiken, of een switch-blok, of meerdere uitzonderingen nesten. Deze uitzonderingen kunnen verschillende exception-classes gebruiken en verschillende foutmeldingen retourneren:

<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Fout op regel '.$this->getLine().' in '.$this->getFile()
: <b>'.$this->getMessage().'</b> is geen geldig e-mailadres
return $errorMsg;
}
}
$email = "someone@example.com";
try
 {
 //Controleer of 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 //check for "example" in mail address
 if(strpos($email, "example") !== FALSE)
  {
  throw new Exception("$email is een voorbeeld e-mail");
  }
 }
catch (customException $e)
 {
 echo $e->errorMessage();
 }
catch(Exception $e)
 {
 echo $e->getMessage();
 }
?>

Example explanation:

Het bovenstaande codevoorbeeld testt twee voorwaarden, als geen van beide voorwaarden wordt vervuld, wordt een uitzondering gegooid:

  1. The customException() class is created as an extension of the old exception class. This way, it inherits all properties and methods of the old class.
  2. Create the errorMessage() function. If the e-mail address is not valid, this function returns an error message.
  3. Het uitvoeren van het "try"-blok, onder de eerste conditie, gooit geen uitzondering.
  4. Vanwege de string "example" in de e-mail, wordt de tweede conditie geactiveerd om de uitzondering te veroorzaken.
  5. Een "catch"-blok vangt de uitzondering op en toont een passende foutmelding

Als de customException niet is opgevangen en alleen de base exception is opgevangen, dan wordt de uitzondering daar behandeld.

Herhalen van de uitzondering

Soms, wanneer een uitzondering wordt gegooid, wilt u mogelijk op een andere manier omgaan met deze uitzondering dan de standaard manier. U kunt een uitzondering opnieuw gooien in een "catch"-blok.

The script should hide system errors from the user. For programmers, system errors may be important, but users are not interested in them. To make it easier for users, you can re-throw exceptions with messages that are more user-friendly:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
  return $errorMsg;
  }
 }
$email = "someone@example.com";
try
 {
 try
  {
  //check for "example" in mail address
  if(strpos($email, "example") !== FALSE)
   {
   //throw exception if email is not valid
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //re-throw exception
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

Example explanation:

The above code checks if the string "example" is present in the e-mail address. If it is, it throws the exception again:

  1. The customException() class is created as an extension of the old exception class. This way, it inherits all properties and methods of the old class.
  2. Create the errorMessage() function. If the e-mail address is not valid, this function returns an error message.
  3. Set the $email variable to a valid e-mail address but containing the string "example".
  4. The "try" block contains another "try" block, allowing the exception to be thrown again.
  5. An exception was triggered because the e-mail contained the string "example".
  6. "catch" caught the exception and re-threw "customException".
  7. Captured "customException" and displayed an error message.

Als een uitzondering niet wordt gevangen in de huidige 'try'-codeblok, zal het op hoger niveau een catch-codeblok zoeken.

Instellen van een top-level uitzonderingsafhandelaar (Top Level Exception Handler)

De set_exception_handler() functie kan een gebruikersdefinieerde functie instellen om alle niet-gevangen uitzonderingen te verwerken.

<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Ongevangen Exception ontstaan');
?>

De output van de bovenstaande code zou er ongeveer zo uit moeten zien:

Exception: Ongevangen Exception ontstaan

In de bovenstaande code bestaat er geen 'catch'-codeblok, maar wordt de top-level uitzonderingsafhandeling geactiveerd. Deze functie moet worden gebruikt om alle niet-gevangen uitzonderingen te vangen.

Regels voor uitzonderingen

  • Code die uitzonderingsafhandeling vereist, moet in een try-codeblok worden geplaatst om potentiële uitzonderingen te vangen.
  • Elke try- of throw-codeblok moet ten minste één bijbehorende catch-codeblok hebben.
  • Met meerdere catch-blokken kunnen verschillende soorten uitzonderingen worden gevangen.
  • Uitzonderingen kunnen opnieuw worden gegooid (re-thrown) in een catch-blok binnen een try-codeblok.

Kortom: als een uitzondering wordt gegooid, moet deze worden gevangen.