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.