W3docs

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 executes

Pourquoi 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: 13

Re-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 down

throw 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: region

Erreurs courantes

  • Lever une exception sans aucun try/catch en 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 secours set_exception_handler().
  • Lever une chaîne ou un tableau. throw requiert un objet implémentant Throwable ; throw "oops"; est une erreur de syntaxe.
  • Avaler silencieusement les exceptions. Un bloc catch vide 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é

  • throw lève un Throwable et déroule immédiatement la pile jusqu'au catch correspondant 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 Exception pour créer des types d'erreurs nommés ; passez une exception previous pour chaîner les causes.
  • Capturez, ajoutez du contexte et re-levez avec throw pour laisser un gestionnaire externe décider.
  • En PHP 8+, throw fonctionne 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.

Pratique

Pratique
Que fait l'instruction 'throw' en PHP ?
Que fait l'instruction 'throw' en PHP ?
Was this page helpful?