Exception-Klassen
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 66 von 91.
In PHP sind Ausnahmen Objekte, die signalisieren, dass während der Ausführung etwas schiefgelaufen ist. Die Basisklasse für alle Ausnahmen ist Exception, und das Verständnis ihrer Struktur hilft dir, Fehler in deinen OOP-Anwendungen effektiv zu behandeln.
Wenn du eine Ausnahme auslöst, erstellst du eine Instanz der Klasse Exception (oder einer Unterklasse) mit einer Nachricht, die beschreibt, was schiefgelaufen ist:
<?php
class BankAccount {
public function __construct(private float $balance = 0) {}
public function withdraw(float $amount): float {
if ($amount > $this->balance) {
throw new Exception("Insufficient funds");
}
$this->balance -= $amount;
return $amount;
}
}
$account = new BankAccount(100);
$account->withdraw(150);
Dies würde einen Fehler aufgrund einer nicht abgefangenen Ausnahme mit der Nachricht "Insufficient funds" erzeugen.
PHP stellt mehrere integrierte Ausnahme-Klassen für unterschiedliche Situationen bereit. InvalidArgumentException signalisiert ungültige Eingaben, RuntimeException weist auf Fehler während der Ausführung hin, und LogicException steht für Programmierfehler:
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
Jedes exception-Objekt enthält nützliche Informationen: getMessage() gibt die Fehlermeldung zurück, getCode() gibt einen optionalen Fehlercode zurück, und getFile() sowie getLine() zeigen dir, wo die exception ausgelöst wurde. Die Verwendung spezifischer exception-Typen macht die Absicht deines Codes klarer und ermöglicht eine präzisere Fehlerbehandlung.
Aufgabe
EinfachErstelle ein Bestandsverwaltungssystem, das die integrierten Ausnahme-Klassen von PHP verwendet, um verschiedene Arten von Problemen zu signalisieren. Du erstellst einen Produktbestand, bei dem Vorgänge auf bestimmte, aussagekräftige Weise fehlschlagen können.
Du organisierst deinen Code auf drei Dateien:
Product.php: Erstelle eineProduct-Klasse, die einen Artikel im Bestand repräsentiert. Verwende Constructor Promotion für ein öffentliches$sku(String), ein öffentliches$name(String) und ein privates$quantity(Int). Deine Klasse sollte Folgendes enthalten:- Eine Methode
getQuantity(): int, die die aktuelle Menge zurückgibt - Eine Methode
addStock(int $amount): void, die die Menge erhöht. Wenn der Betrag kleiner als 1 ist, wirf eineInvalidArgumentExceptionmit der Nachricht"Amount must be positive" - Eine Methode
removeStock(int $amount): void, die die Menge verringert. Wenn der Betrag kleiner als 1 ist, wirf eineInvalidArgumentExceptionmit der Nachricht"Amount must be positive". Wenn der Betrag die aktuelle Menge überschreitet, wirf eineRuntimeExceptionmit der Nachricht"Insufficient stock"
- Eine Methode
Inventory.php: Erstelle eineInventory-Klasse, die eine Sammlung von Produkten verwaltet. Binde die Product-Datei ein. Deine Klasse sollte Folgendes enthalten:- Ein privates Array zum Speichern von Produkten, indiziert nach SKU
- Eine Methode
addProduct(Product $product): void, die ein Produkt hinzufügt. Wenn bereits ein Produkt mit derselben SKU existiert, wirf eineLogicExceptionmit der Nachricht"Product already exists: [sku]" - Eine Methode
getProduct(string $sku): Product, die ein Produkt anhand der SKU zurückgibt. Wenn es nicht gefunden wird, wirf eineInvalidArgumentExceptionmit der Nachricht"Product not found: [sku]"
main.php: Binde die Inventory-Datei ein. Du erhältst drei Eingaben: eine SKU, einen Produktnamen und eine Operation ("add","remove"oder"duplicate").Erstelle ein
Inventoryund füge ein neuesProductmit der angegebenen SKU, dem angegebenen Namen und einer anfänglichen Menge von10hinzu.Führe abhängig von der Operation Folgendes aus:
"add": RufeaddStock(5)für das Produkt auf und gib anschließend"Stock updated: [quantity]"aus"remove": RuferemoveStock(15)für das Produkt auf (dies sollte eine Ausnahme auslösen)"duplicate": Versuche, ein weiteres Produkt mit derselben SKU hinzuzufügen (dies sollte eine Ausnahme auslösen)
Wenn eine Ausnahme ausgelöst wird, gib den Klassennamen der Ausnahme gefolgt von
": "und der Nachricht der Ausnahme aus. Verwende die PHP-Funktionget_class(), um den Klassennamen abzurufen.
Diese Herausforderung zeigt, wie verschiedene Ausnahme-Typen unterschiedliche Arten von Problemen vermitteln — ungültige Eingaben, Laufzeitfehler und Logikfehler — und dadurch die Fehlerbehandlung deines Codes präziser und aussagekräftiger machen.
Probier es selbst
<?php
require_once 'Inventory.php';
// Eingaben lesen
$sku = trim(fgets(STDIN));
$name = trim(fgets(STDIN));
$operation = trim(fgets(STDIN));
try {
// TODO: Erstelle ein Inventory
// TODO: Erstelle ein Product mit der gegebenen SKU, dem Namen und der Anfangsmenge von 10
// TODO: Füge das Produkt dem Inventory hinzu
// TODO: Basierend auf der Operation:
// - "add": Call addStock(5) on the product, then print "Stock updated: [quantity]"
// - "remove": Rufe removeStock(15) auf dem Produkt auf
// - "duplicate": Versuche, ein weiteres Produkt mit derselben SKU hinzuzufügen
} catch (Exception $e) {
// TODO: Gib den Exception-Klassennamen gefolgt von ": " und der Nachricht aus
// Hint: Verwende get_class($e), um den Klassennamen zu erhalten
}
?>Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in OOPKlassen vs. ObjekteDas Schlüsselwort $thisMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDas Schlüsselwort parent::MethodenüberschreibungDas Schlüsselwort finalAbstrakte KlassenRückblick – Mitarbeiterhierarchie7Kapselung
Öffentlich, geschützt, privatZugriffsmodifikatoren im DetailGetter und SetterInformationsverbergungKonstruktor-Promotion (8.0)Wiederholung – System zur Verwaltung von Schülerdatensätzen2Namespaces & Autoloading
Einführung in NamespacesDas use-SchlüsselwortPSR-4-Autoloading-StandardComposer-AutoloaderRückblick – Organisiertes Projekt5Schnittstellen & Verträge
Einführung in SchnittstellenSchnittstellen implementierenMehrere Schnittstellen implementierenSchnittstelle vs. abstrakte KlasseTyp-Hinweise mit SchnittstellenRückblick – Formrechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objektklonen__serialize & __unserializeRückblick – Benutzerdefinierte Sammlung11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenBenutzerdefinierte Exception-HierarchieTry, Catch, FinallyRückblick – Formularvalidator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klassen-Eigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenSchreibgeschützte Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphie
Methodenüberschreibung erneut betrachtetPolymorphie über SchnittstellenTyp-Hinweise & Union-TypenSpätes statisches BindenRückblick – Zahlungsabwickler9Traits
Einführung in TraitsMehrere Traits verwendenAuflösung von Trait-KonfliktenAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungÜbe selbstständig: Online-PHP-Compiler