Menu
Coddy logo textTech

Benutzerdefinierte Exception-Hierarchie

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 67 von 91.

Während die integrierten Exception-Klassen von PHP häufige Szenarien abdecken, benötigen echte Anwendungen oft spezifischere Fehlertypen. Das Erstellen einer benutzerdefinierten Exception-Hierarchie ermöglicht es dir, Exceptions zu definieren, die zu deiner Domäne passen, und sie auf verschiedenen Ebenen der Spezifität abzufangen.

Um eine benutzerdefinierte Ausnahme zu erstellen, erweiterst du einfach die Klasse Exception oder eine ihrer Unterklassen:

<?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;
    }
}

Beachte, dass InsufficientFundsException PaymentException erweitert und nicht direkt Exception. Dadurch entsteht eine Hierarchie, in der du alle zahlungsbezogenen Ausnahmen mit einem einzigen catch-Block abfangen oder bestimmte Ausnahmen einzeln behandeln kannst.

Benutzerdefinierte exceptions können zusätzliche Eigenschaften und Methoden enthalten, die für den Fehler relevant sind. Hier liefert getShortfall() nützliche Informationen, die eine allgemeine exception nicht bieten könnte:

<?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;
    }
}

Eine gut gestaltete Ausnahmehierarchie macht deinen Code wartbarer. Beim Abfangen von Ausnahmen kannst du je nach Bedarf allgemein oder spezifisch vorgehen, und die Ausnahmeobjekte selbst enthalten aussagekräftigen Kontext darüber, was schiefgelaufen ist.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Auftragsverarbeitungssystem mit einer benutzerdefinierten Ausnahmehierarchie, die verschiedene Arten von Auftragsfehlern behandelt. Du erstellst Ausnahmen, die aussagekräftigen Kontext darüber enthalten, was schiefgelaufen ist, wodurch die Fehlerbehandlung präziser und informativer wird.

Du organisierst deinen Code auf vier Dateien verteilt:

  • OrderException.php: Erstelle eine Basisklasse OrderException, die Exception erweitert. Sie dient als übergeordnete Klasse für alle auftragsbezogenen Ausnahmen und ermöglicht es dir bei Bedarf, jedes Auftragsproblem mit einem einzigen catch-Block abzufangen.
  • OutOfStockException.php: Erstelle eine Klasse OutOfStockException, die OrderException erweitert. Diese Ausnahme soll in ihrem Konstruktor einen Produktnamen und die angeforderte Menge akzeptieren. Verwende Konstruktor-Promotion für diese privaten Eigenschaften. Rufe den übergeordneten Konstruktor mit einer Nachricht im Format "[productName] is out of stock (requested: [quantity])" auf. Füge eine Methode getProductName(): string hinzu, die den Produktnamen zurückgibt.
  • InvalidQuantityException.php: Erstelle eine Klasse InvalidQuantityException, die OrderException erweitert. Diese Ausnahme soll in ihrem Konstruktor einen Mengenwert akzeptieren und dabei Konstruktor-Promotion für eine private Eigenschaft verwenden. Rufe den übergeordneten Konstruktor mit der Nachricht "Invalid quantity: [quantity]" auf. Füge eine Methode getQuantity(): int hinzu, die den Mengenwert zurückgibt.
  • main.php: Binde alle drei Ausnahme-Dateien ein. Du erhältst zwei Eingaben: einen Produktnamen und eine Menge (als Zeichenkette, die in eine Ganzzahl umgewandelt werden muss).

    Wirf abhängig vom Mengenwert die passende Ausnahme:

    • Wenn die Menge kleiner als 1 ist, wirf eine InvalidQuantityException
    • Wenn die Menge größer als 100 ist, wirf eine OutOfStockException (um einen unzureichenden Lagerbestand zu simulieren)
    • Andernfalls gib "Order placed: [quantity]x [productName]" aus

    Fange Ausnahmen mithilfe der Hierarchie ab. Fange zuerst InvalidQuantityException ab und gib "Quantity error: [message] (value: [quantity])" unter Verwendung der Nachricht der Ausnahme und der Methode getQuantity() aus. Fange anschließend OutOfStockException ab und gib "Stock error: [message] (product: [productName])" unter Verwendung der Nachricht der Ausnahme und der Methode getProductName() aus.

Mit dieser Hierarchie kannst du bestimmte Ausnahmen einzeln behandeln und hast gleichzeitig die Möglichkeit, alle auftragsbezogenen Probleme über die Basisklasse OrderException abzufangen. Die benutzerdefinierten Methoden jeder Ausnahme liefern Kontext, den eine allgemeine Ausnahme nicht bieten könnte.

Probier es selbst

<?php
// Alle Exception-Dateien einbinden
require_once 'OrderException.php';
require_once 'OutOfStockException.php';
require_once 'InvalidQuantityException.php';

// Eingabe lesen
$productName = trim(fgets(STDIN));
$quantity = intval(trim(fgets(STDIN)));

// TODO: Verwende try-catch, um die Bestellverarbeitung zu handhaben
// Innerhalb des try-Blocks:
//   - Wenn quantity < 1, throw InvalidQuantityException
//   - Wenn quantity > 100, throw OutOfStockException
//   - Andernfalls, print "Order placed: [quantity]x [productName]"
//
// Catch InvalidQuantityException zuerst:
//   - Print "Quantity error: [message] (value: [quantity])" mit getMessage() und getQuantity()
//
// Catch OutOfStockException:
//   - Print "Stock error: [message] (product: [productName])" mit getMessage() und getProductName()

?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-PHP-Compiler