try
Apprenez comment PHP try/catch/finally gère les exceptions. Couvre les blocs catch multiples, les types union, le rethrow et les pièges courants.
Le mot-clé PHP try
Le mot-clé try marque un bloc de code susceptible de lever une exception — un objet signalant que quelque chose s'est mal passé et que l'exécution normale ne peut pas continuer. Lorsqu'une exception est levée à l'intérieur d'un bloc try, PHP arrête d'exécuter le reste de ce bloc et recherche un bloc catch correspondant pour la gérer. Un bloc finally optionnel s'exécute ensuite, quoi qu'il se soit passé.
Cette page couvre la syntaxe try/catch/finally, la façon dont plusieurs blocs catch sont mis en correspondance, la capture de plusieurs types d'exceptions à la fois, le rethrow, et les pièges qui font trébucher les développeurs. Si vous êtes novice en matière de levée d'erreurs, lisez d'abord Les exceptions en PHP.
Syntaxe
try {
// Code that may throw an exception
} catch (ExceptionType $e) {
// Code that runs if an exception of ExceptionType (or a subclass) is thrown
} finally {
// Optional: always runs, whether or not an exception was thrown
}Un bloc try doit être suivi d'au moins un bloc catch, ou d'un bloc finally, ou des deux — un try seul est une erreur de syntaxe. La variable dans catch (ExceptionType $e) contient l'objet exception levé, que vous interrogez avec des méthodes telles que $e->getMessage().
Premier exemple
La fonction ci-dessous lève une exception lorsqu'on lui demande de diviser par zéro. Le bloc try l'appelle, le bloc catch signale le problème, et finally s'exécute toujours :
<?php
function divide($dividend, $divisor)
{
if ($divisor == 0) {
throw new Exception("Cannot divide by zero.");
}
return $dividend / $divisor;
}
try {
$result = divide(10, 0);
echo $result; // skipped — divide() threw before returning
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . PHP_EOL;
} finally {
echo "Done." . PHP_EOL;
}Résultat :
Error: Cannot divide by zero.
Done.Remarquez que echo $result; ne s'exécute jamais : dès que divide(10, 0) lève une exception, le contrôle saute directement au bloc catch. Le bloc finally s'exécute ensuite. Si vous appelez divide(10, 2) à la place, aucune exception n'est levée, le bloc try affiche 5, et finally affiche quand même Done..
Plusieurs blocs catch
Un seul try peut être suivi de plusieurs blocs catch. PHP les vérifie de haut en bas et exécute le premier dont le type correspond à l'exception levée (la correspondance inclut les sous-classes). Listez les types plus spécifiques avant les types plus généraux — un catch (Exception $e) en tête avalerait tout ce qui suit.
<?php
try {
$value = "5";
if (!is_int($value)) {
throw new TypeError("Expected an integer.");
}
} catch (TypeError $e) {
echo "Type problem: " . $e->getMessage() . PHP_EOL;
} catch (Exception $e) {
echo "Other problem: " . $e->getMessage() . PHP_EOL;
}Résultat :
Type problem: Expected an integer.Capturer plusieurs types dans un seul bloc
Lorsque deux types d'exceptions doivent être gérés de la même façon, combinez-les avec une barre verticale (|) — une fonctionnalité ajoutée dans PHP 7.1 — plutôt que de dupliquer le bloc :
<?php
try {
throw new RuntimeException("Network timed out.");
} catch (RuntimeException | LogicException $e) {
echo "Handled: " . $e->getMessage() . PHP_EOL;
}Résultat :
Handled: Network timed out.Comportement de finally
Le bloc finally s'exécute même si le bloc try ou catch exécute un return. C'est donc le bon endroit pour le nettoyage — fermeture de fichiers, libération de verrous, annulation d'une transaction — qui doit avoir lieu sur chaque chemin d'exécution :
<?php
function readConfig()
{
try {
return "config loaded";
} finally {
echo "Cleanup ran." . PHP_EOL;
}
}
echo readConfig() . PHP_EOL;Résultat :
Cleanup ran.
config loadedLe bloc finally s'exécute avant que la fonction retourne réellement sa valeur. Évitez de retourner depuis finally lui-même : un return là-dedans remplace la valeur de try/catch et écarte silencieusement toute exception en cours de propagation.
Rethrow d'une exception
Un bloc catch peut effectuer un travail partiel — journaliser l'erreur, ajouter du contexte — puis relancer l'exception afin qu'un appelant plus haut dans la pile puisse décider quoi faire. Utilisez throw $e; pour relancer le même objet :
<?php
try {
try {
throw new Exception("Disk full.");
} catch (Exception $e) {
echo "Logging: " . $e->getMessage() . PHP_EOL;
throw $e; // hand it to the outer handler
}
} catch (Exception $e) {
echo "Outer handler: " . $e->getMessage() . PHP_EOL;
}Résultat :
Logging: Disk full.
Outer handler: Disk full.Pièges courants
trya besoin d'un partenaire. Un bloctryseul ne se parse pas — associez-le à au moins uncatchou unfinally.- Les erreurs ne sont pas toutes des exceptions. De nombreux avertissements d'exécution (une variable non définie, un
fopen()échoué) ne sont pas levés comme des exceptions, donccatchne les verra pas. Utilisezset_error_handler()ou vérifiez les valeurs de retour pour ceux-là. Les objetsErrorfatals (commeTypeError) peuvent être capturés car ils implémententThrowable. - Ordonnez vos blocs
catchdu plus spécifique au plus général. Un largecatch (Exception $e)placé en premier masque tous les blocs suivants. - N'avalez pas silencieusement les erreurs. Un bloc
catchvide dissimule l'échec ; journalisez au minimum$e->getMessage()pour que le problème soit visible. finallypeut masquer les exceptions. Retourner depuisfinallyécarte à la fois la valeur de retour detryet toute exception en vol.
Quand utiliser try ?
Recourez à try/catch lorsqu'un échec est exceptionnel et que le code appelant peut raisonnablement y réagir : une connexion à la base de données qui se coupe, une API qui retourne une erreur, une saisie utilisateur invalide que vous souhaitez rejeter proprement. Pour un flux de contrôle ordinaire (une clé est-elle présente dans un tableau ? une chaîne est-elle vide ?), utilisez des conditions normales — les exceptions sont faites pour le chemin anormal, pas pour la ramification quotidienne.
Voir aussi
catch— le bloc qui gère une exception levée.finally— code qui s'exécute toujours aprèstry/catch.throw— lever une exception vous-même.- La classe Exception — le type de base et ses méthodes.
- Les exceptions en PHP — la vue d'ensemble de la gestion des erreurs.
set_exception_handler()— capturer les exceptions qui échappent à touttry.