Exception în PHP

Erori și excepții PHP 5+ (excepția anterioară: PHP 5.3+)

Clasa de bază pentru excepții. Extinde-o ca să creezi tipuri proprii de erori pentru aplicația ta.

Sintaxă
new Exception(string $message = "", int $code = 0, ?Throwable $previous = null)

Ce face Exception

Un obiect Exception conține mesajul (getMessage()), un cod numeric (getCode()), fișierul și linia unde a fost creat (getFile(), getLine()), lista apelurilor (getTraceAsString()) și excepția care a provocat-o (getPrevious()).

PHP are deja multe tipuri utile: InvalidArgumentException (argument greșit), RuntimeException (eroare la rulare), LogicException, DomainException, OutOfRangeException. Pentru erorile aplicației tale, creează clase proprii care extind Exception sau unul dintre aceste tipuri. Așa le poți prinde separat.

Erorile limbajului au propria ierarhie, care pornește de la Error: TypeError, ValueError, ArithmeticError, DivisionByZeroError. Atât Exception, cât și Error implementează interfața Throwable.

Parametri

Parametru Descriere
$message Mesajul erorii.
$code Opțional. Un cod numeric al erorii.
$previous Opțional. Excepția originală, când arunci o excepție nouă pornind de la alta.

Exemple

Exemplul 1: Excepție proprie cu date în plus

<?php
class StocInsuficientException extends RuntimeException
{
    public function __construct(public readonly string $produs, public readonly int $disponibil)
    {
        parent::__construct("Stoc insuficient pentru $produs (mai sunt $disponibil buc.)");
    }
}

function comanda(string $produs, int $bucati): string
{
    $stoc = ["Mouse" => 3];
    if ($bucati > ($stoc[$produs] ?? 0)) {
        throw new StocInsuficientException($produs, $stoc[$produs] ?? 0);
    }
    return "Comandă plasată: $bucati x $produs";
}

try {
    echo comanda("Mouse", 2) . "\n";
    echo comanda("Mouse", 5) . "\n";
} catch (StocInsuficientException $e) {
    echo $e->getMessage() . "\n";
    echo "Poți comanda maximum " . $e->disponibil . " bucăți.";
}

Rezultat

Comandă plasată: 2 x Mouse
Stoc insuficient pentru Mouse (mai sunt 3 buc.)
Poți comanda maximum 3 bucăți.

Exemplul 2: Metodele unei excepții

<?php
try {
    throw new DomainException("Cod poștal invalid", 422);
} catch (Exception $e) {
    echo get_class($e) . "\n";
    echo $e->getMessage() . "\n";
    echo $e->getCode() . "\n";
    echo "Linia " . $e->getLine();
}

Rezultat

DomainException
Cod poștal invalid
422
Linia 3

Exemplul 3: Excepție nouă care păstrează cauza

Al treilea parametru leagă excepțiile între ele. Mesajul tehnic rămâne disponibil pentru jurnal, iar utilizatorul vede un mesaj clar.

<?php
function citesteConfig(string $json): array
{
    try {
        return json_decode($json, true, 512, JSON_THROW_ON_ERROR);
    } catch (JsonException $e) {
        throw new RuntimeException("Fișierul de configurare este stricat", 0, $e);
    }
}

try {
    citesteConfig("{site: dexblog}");
} catch (RuntimeException $e) {
    echo $e->getMessage() . "\n";
    echo "Cauza: " . get_class($e->getPrevious()) . " - " . $e->getPrevious()->getMessage();
}

Rezultat

Fișierul de configurare este stricat
Cauza: JsonException - Syntax error

Greșeli frecvente

  • Arunci peste tot new Exception(...). Codul care prinde nu poate deosebi o eroare de validare de una de bază de date. Folosește tipuri specifice.
  • Afișezi vizitatorilor $e->getMessage() pentru erori tehnice (de exemplu de la baza de date). Mesajele pot conține date interne. Arată un mesaj general și scrie detaliile în jurnal.

Comenzi înrudite

  • try / catch / finally / throw: Prinde erorile (excepțiile) apărute într-un bloc de cod, ca scriptul să nu se oprească brusc.
  • set_exception_handler: Setează funcția care rulează când o excepție nu este prinsă de niciun bloc catch.
  • trigger_error: Generează un mesaj de eroare de nivel utilizator (notificare, avertisment, deprecated), ca cele produse de PHP.