Gerarchia di eccezioni personalizzata
Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 67 di 91.
Sebbene le classi di eccezione integrate in PHP coprano gli scenari più comuni, le applicazioni reali spesso necessitano di tipi di errore più specifici. Creare una gerarchia di eccezioni personalizzata ti permette di definire eccezioni adatte al tuo dominio e intercettarle a diversi livelli di specificità.
Per creare un'eccezione personalizzata, estendi semplicemente la classe Exception o una delle sue sottoclassi:
<?php
class PaymentException extends Exception {}
class InsufficientFundsException extends PaymentException {
public function __construct(
private float $required,
private float $available
) {
parent::__construct("Need $required but only $available available");
}
public function getShortfall(): float {
return $this->required - $this->available;
}
}
Nota come InsufficientFundsException estende PaymentException, non direttamente Exception. Questo crea una gerarchia che ti permette di intercettare tutte le eccezioni relative ai pagamenti con un solo blocco catch, oppure di gestirle singolarmente.
Le eccezioni personalizzate possono includere proprietà e metodi aggiuntivi pertinenti all’errore. Qui, getShortfall() fornisce informazioni utili che un’eccezione generica non potrebbe offrire:
<?php
class Wallet {
public function __construct(private float $balance) {}
public function pay(float $amount): void {
if ($amount > $this->balance) {
throw new InsufficientFundsException($amount, $this->balance);
}
$this->balance -= $amount;
}
}
Una gerarchia di eccezioni ben progettata rende il tuo codice più facile da mantenere. Quando intercetti le eccezioni, puoi essere più generico o specifico secondo necessità, e gli oggetti eccezione stessi contengono informazioni significative su cosa è andato storto.
Sfida
FacileCreiamo un sistema di elaborazione degli ordini con una gerarchia di eccezioni personalizzate che gestisce diversi tipi di errori negli ordini. Creerai eccezioni che contengono informazioni utili su cosa è andato storto, rendendo la gestione degli errori più precisa e informativa.
Organizzerai il codice in quattro file:
OrderException.php: crea una classe baseOrderExceptionche estendeException. Funge da classe genitore per tutte le eccezioni relative agli ordini e ti permette, quando necessario, di intercettare qualsiasi problema relativo a un ordine con un unico blocco catch.OutOfStockException.php: crea una classeOutOfStockExceptionche estendeOrderException. Il costruttore di questa eccezione deve accettare il nome di un prodotto e la quantità richiesta. Usa la promozione delle proprietà del costruttore per dichiarare queste proprietà private. Chiama il costruttore della classe genitore con un messaggio nel formato"[productName] is out of stock (requested: [quantity])". Aggiungi un metodogetProductName(): stringche restituisce il nome del prodotto.InvalidQuantityException.php: crea una classeInvalidQuantityExceptionche estendeOrderException. Il costruttore di questa eccezione deve accettare un valore di quantità e usare la promozione delle proprietà del costruttore per dichiararlo come proprietà privata. Chiama il costruttore della classe genitore con il messaggio"Invalid quantity: [quantity]". Aggiungi un metodogetQuantity(): intche restituisce il valore della quantità.main.php: includi tutti e tre i file delle eccezioni. Riceverai due input: il nome di un prodotto e una quantità (come stringa da convertire in intero).In base al valore della quantità, lancia l'eccezione appropriata:
- Se la quantità è minore di 1, lancia un'eccezione
InvalidQuantityException - Se la quantità è maggiore di 100, lancia un'eccezione
OutOfStockException(per simulare scorte insufficienti) - Altrimenti, stampa
"Order placed: [quantity]x [productName]"
Intercetta le eccezioni usando la gerarchia. Intercetta prima
InvalidQuantityExceptione stampa"Quantity error: [message] (value: [quantity])"usando il messaggio dell'eccezione e il metodogetQuantity(). Poi intercettaOutOfStockExceptione stampa"Stock error: [message] (product: [productName])"usando il messaggio dell'eccezione e il metodogetProductName().- Se la quantità è minore di 1, lancia un'eccezione
Questa gerarchia ti permette di gestire separatamente le eccezioni specifiche, mantenendo al contempo la possibilità di intercettare tutti i problemi relativi agli ordini tramite la classe base OrderException. I metodi personalizzati di ciascuna eccezione forniscono informazioni contestuali che un'eccezione generica non potrebbe offrire.
Provalo tu
<?php
// Includi tutti i file delle eccezioni
require_once 'OrderException.php';
require_once 'OutOfStockException.php';
require_once 'InvalidQuantityException.php';
// Leggi l'input
$productName = trim(fgets(STDIN));
$quantity = intval(trim(fgets(STDIN)));
// TODO: Usa try-catch per gestire l'elaborazione dell'ordine
// All'interno del blocco try:
// - Se quantity < 1, lancia InvalidQuantityException
// - Se quantity > 100, lancia OutOfStockException
// - Altrimenti, stampa "Order placed: [quantity]x [productName]"
//
// Intercetta prima InvalidQuantityException:
// - Stampa "Quantity error: [message] (value: [quantity])" usando getMessage() e getQuantity()
//
// Intercetta OutOfStockException:
// - Stampa "Stock error: [message] (product: [productName])" usando getMessage() e getProductName()
?>Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave $thisMetodiProprietàCostruttore (__construct)Distruttore (__destruct)Riepilogo - Calcolatrice semplice4Ereditarietà
Ereditarietà di baseLa parola chiave parent::Sovrascrittura dei metodiLa parola chiave finalClassi astratteRiepilogo - Gerarchia dei dipendenti7Incapsulamento
Pubblico, Protetto, PrivatoApprofondimento sui modificatori di accessoGetter e SetterOccultamento delle informazioniPromozione dei parametri del costruttore (8.0)Riepilogo - Sistema di gestione dei registri degli studenti10Concetti avanzati di programmazione a oggetti
Composizione vs ereditarietàDependency InjectionClassi anonimeEnumerazioni (PHP 8.1)Fibers (PHP 8.1)Approfondimento sulla clonazione degli oggettiGeneratori e iteratori13Modelli di progettazione, parte 2
Modello CommandModello AdapterModello DecoratorModello Template MethodModello StateModello CompositeModello Repository2Namespace e autoloading
Introduzione ai namespaceLa keyword useStandard di autoloading PSR-4Autoloader di ComposerRiepilogo - Progetto organizzato5Interfacce e contratti
Introduzione alle interfacceImplementare le interfacceImplementare più interfacceInterfaccia vs classe astrattaType hinting con le interfacceRiepilogo - Calcolatore di forme8Metodi magici
Introduzione ai metodi magici__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e clonazione degli oggetti__serialize e __unserializeRiepilogo - Collezione personalizzata11Sistema dei tipi e gestione degli errori
Dichiarazioni di tipoTipi nullableTipi unione e intersezioneClassi di eccezioneGerarchia di eccezioni personalizzataTry, Catch, FinallyRiepilogo - Validatore di moduli14Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Proprietà delle classi
Proprietà di istanza e staticheCostanti nelle classiMetodi e proprietà staticiProprietà private e protectedProprietà readonly (PHP 8.1)Riepilogo - Gestore di conti bancari6Polimorfismo
Ridefinizione dei metodi, ripresaPolimorfismo tramite interfacceSuggerimenti sui tipi e tipi UnionBinding statico tardivoRiepilogo - Processore di pagamenti9Tratti
Introduzione ai trattiUtilizzare più trattiRisoluzione dei conflitti tra trattiMetodi astratti nei trattiTratti vs ereditarietà12Design pattern - Parte 1
Introduzione ai design patternPattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore PHP online