throw
En PHP, le mot-clé "throw" permet de déclencher une exception pour gérer les erreurs et les conditions inattendues dans votre code.
Le mot-clé PHP throw
Le mot-clé throw interrompt l'exécution normale à l'endroit où il est invoqué et lève une exception — un objet signalant qu'une erreur s'est produite. Le contrôle remonte immédiatement la pile d'appels jusqu'à atteindre un bloc catch correspondant. Si aucun catch ne correspond, PHP arrête le script avec une erreur fatale.
Cette page couvre la syntaxe de throw, quand l'utiliser plutôt que de retourner une valeur d'erreur, comment lever des exceptions intégrées et personnalisées, comment re-lever et chaîner des exceptions, et la fonctionnalité PHP 8 permettant d'utiliser throw comme expression. Pour une vue d'ensemble, consultez Les exceptions en PHP et le flux try/catch/finally.
Syntaxe
throw new Exception("Error message here");throw doit recevoir une valeur qui est une instance de Throwable — en pratique une Exception (ou l'une de ses sous-classes) ou une Error. La chaîne passée au constructeur devient le message de l'exception, que vous lisez ensuite avec getMessage().
Étant donné qu'une exception levée déroule la pile, tout code situé après throw dans le même bloc ne s'exécute jamais :
throw new Exception("stop here");
echo "this line is unreachable"; // never executesPourquoi utiliser throw plutôt que retourner une erreur ?
Retourner une valeur spéciale (comme false ou -1) pour signaler un échec oblige chaque appelant à se souvenir de la vérifier, et la signification de la valeur est facile à perdre. throw rend l'échec impossible à ignorer : l'exception se propage automatiquement jusqu'à ce que quelque chose la gère, et elle porte un message, un code, une trace de pile, ainsi que le fichier et la ligne où elle s'est produite.
Utilisez throw pour les conditions exceptionnelles dont la fonction actuelle ne peut pas raisonnablement se remettre — arguments invalides, connexion à la base de données échouée, fichier requis manquant — et laissez un appelant plus haut dans la pile décider de la marche à suivre.
Un exemple de base
Ici, une fonction divide() lève une exception lorsqu'on lui demande de diviser par zéro, et l'appelant la capture :
<?php
function divide(int $numerator, int $denominator): float
{
if ($denominator === 0) {
throw new InvalidArgumentException("Cannot divide by zero.");
}
return $numerator / $denominator;
}
try {
echo divide(10, 2), PHP_EOL; // 5
echo divide(10, 0), PHP_EOL; // throws before printing
} catch (InvalidArgumentException $e) {
echo "Caught: " . $e->getMessage() . PHP_EOL;
}Résultat :
5
Caught: Cannot divide by zero.Le premier appel réussit et affiche 5. Le second appel lève une exception, donc son echo ne s'exécute jamais et le contrôle saute directement au bloc catch.
Lever une exception personnalisée
Étendre Exception vous permet de donner à chaque type d'erreur son propre nom, afin que les appelants puissent catch exactement les échecs qui les concernent et ignorer les autres :
<?php
class InsufficientFundsException extends Exception {}
function withdraw(float $balance, float $amount): float
{
if ($amount > $balance) {
throw new InsufficientFundsException(
"Cannot withdraw $amount; balance is only $balance."
);
}
return $balance - $amount;
}
try {
echo withdraw(100, 250), PHP_EOL;
} catch (InsufficientFundsException $e) {
echo "Declined: " . $e->getMessage() . PHP_EOL;
}Résultat :
Declined: Cannot withdraw 250; balance is only 100.Consultez Classes d'exceptions personnalisées pour en savoir plus sur l'extension d'Exception.
Message, code et exception précédente
Le constructeur d'Exception accepte trois arguments — message, code et une exception previous. Le troisième vous permet d'encapsuler une erreur de bas niveau dans une erreur plus significative sans perdre la cause originale (c'est ce qu'on appelle le chaînage d'exceptions) :
<?php
try {
try {
throw new RuntimeException("Disk read failed", 13);
} catch (RuntimeException $low) {
// Re-throw a higher-level exception, keeping the original as the cause.
throw new Exception("Could not load config", 0, $low);
}
} catch (Exception $e) {
echo $e->getMessage() . PHP_EOL; // Could not load config
echo "Caused by: " . $e->getPrevious()->getMessage() . PHP_EOL; // Disk read failed
echo "Original code: " . $e->getPrevious()->getCode() . PHP_EOL; // 13
}Résultat :
Could not load config
Caused by: Disk read failed
Original code: 13Re-lever une exception dans un bloc catch
Vous n'avez pas à gérer complètement une exception là où vous la capturez. Un bloc catch peut effectuer quelques opérations (la journaliser, ajouter du contexte) puis throw à nouveau pour laisser un gestionnaire externe terminer le travail :
<?php
function loadUser(int $id): array
{
try {
throw new RuntimeException("Database is down");
} catch (RuntimeException $e) {
error_log("loadUser($id) failed: " . $e->getMessage());
throw $e; // pass it on
}
}
try {
loadUser(7);
} catch (RuntimeException $e) {
echo "Handled at top level: " . $e->getMessage() . PHP_EOL;
}Résultat :
Handled at top level: Database is downthrow comme expression (PHP 8+)
Depuis PHP 8.0, throw est une expression et pas seulement une instruction, vous pouvez donc l'utiliser dans des endroits qui attendent une valeur — comme les opérateurs ?: et ?? ou une fonction fléchée :
<?php
function getConfig(array $config, string $key): string
{
// Throw inline when the key is missing.
return $config[$key] ?? throw new InvalidArgumentException("Missing key: $key");
}
echo getConfig(['env' => 'prod'], 'env'), PHP_EOL; // prod
try {
getConfig(['env' => 'prod'], 'region');
} catch (InvalidArgumentException $e) {
echo $e->getMessage() . PHP_EOL;
}Résultat :
prod
Missing key: regionErreurs courantes
- Lever une exception sans aucun
try/catchen amont dans la pile. Une exception non capturée devient une erreur fatale et arrête le script. Capturez-la toujours quelque part, ou enregistrez un gestionnaire de secoursset_exception_handler(). - Lever une chaîne ou un tableau.
throwrequiert un objet implémentantThrowable;throw "oops";est une erreur de syntaxe. - Avaler silencieusement les exceptions. Un bloc
catchvide masque les bugs. Journalisez au minimum le message, ou re-levez l'exception. - Utiliser les exceptions pour le flux de contrôle ordinaire. Lever une exception à chaque branche attendue (par exemple, "utilisateur introuvable" lors d'une recherche habituelle) est lent et source de confusion — réservez-les aux cas véritablement exceptionnels.
Résumé
throwlève unThrowableet déroule immédiatement la pile jusqu'aucatchcorrespondant le plus proche.- Préférez-le aux valeurs de retour magiques afin que les échecs ne puissent pas être ignorés silencieusement.
- Sous-classez
Exceptionpour créer des types d'erreurs nommés ; passez une exceptionpreviouspour chaîner les causes. - Capturez, ajoutez du contexte et re-levez avec
throwpour laisser un gestionnaire externe décider. - En PHP 8+,
throwfonctionne comme une expression dans??,?:et les fonctions fléchées.
Continuez avec le bloc try, le bloc catch et finally pour découvrir le cycle complet de gestion des exceptions.