Try, Catch, Finally
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 68 von 91.
Nachdem Sie nun wissen, wie man Exceptions erstellt und auslöst, müssen Sie lernen, wie man sie abfängt. Die try-catch-finally-Struktur ermöglicht es Ihnen, Exceptions elegant zu behandeln, anstatt sie Ihre Anwendung zum Absturz bringen zu lassen.
Umschließen Sie Code, der eine Exception auslösen könnte, mit einem try-Block und behandeln Sie die Exception anschließend in einem catch-Block:
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
$calc = new Calculator();
try {
echo $calc->divide(10, 0);
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage();
}
Ausgabe:
Error: Cannot divide by zeroSie können verschiedene Exception-Typen mit mehreren catch-Blöcken abfangen. PHP prüft diese in der Reihenfolge, platzieren Sie daher spezifischere Exceptions zuerst:
<?php
try {
// riskanter Code
} catch (InvalidArgumentException $e) {
echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
echo "Something went wrong: " . $e->getMessage();
}
Der finally-Block wird unabhängig davon ausgeführt, ob eine Exception ausgelöst oder abgefangen wurde. Er eignet sich hervorragend für Bereinigungsaufgaben wie das Schließen von Verbindungen:
<?php
try {
echo "Attempting operation\n";
throw new Exception("Failed");
} catch (Exception $e) {
echo "Caught: " . $e->getMessage() . "\n";
} finally {
echo "Cleanup complete";
}
Ausgabe:
Attempting operation
Caught: Failed
Cleanup completeDer finally-Block wird auch dann ausgeführt, wenn Sie aus den try- oder catch-Blöcken zurückkehren, was ihn für wesentliche Bereinigungsoperationen zuverlässig macht.
Aufgabe
EinfachLassen Sie uns ein Dateiverarbeitungssystem erstellen, das demonstriert, wie try-catch-finally zusammenarbeitet, um Fehler elegant zu behandeln und gleichzeitig sicherzustellen, dass Bereinigungsarbeiten immer durchgeführt werden.
Sie werden Ihren Code über drei Dateien organisieren:
FileException.php— Erstellen Sie eine benutzerdefinierteFileException-Klasse, dieExceptionerweitert. Diese wird dateibezogene Fehler in Ihrem System repräsentieren.FileProcessor.php— Erstellen Sie eineFileProcessor-Klasse, die Dateioperationen simuliert. Binden Sie die FileException-Datei ein. Ihre Klasse sollte Folgendes enthalten:- Eine private boolesche Eigenschaft
$isOpen, die mitfalseinitialisiert wird - Eine Methode
open(string $filename): void, die$isOpenauftruesetzt und"Opening: [filename]"ausgibt. Wenn der Dateiname"invalid.txt"lautet, werfen Sie eineFileExceptionmit der Nachricht"Cannot open file" - Eine Methode
process(): void, die"Processing file..."ausgibt. Wenn$isOpenden Wertfalsehat, werfen Sie eineRuntimeExceptionmit der Nachricht"File not open" - Eine Methode
close(): void, die$isOpenauffalsesetzt und"File closed"ausgibt - Eine Methode
isOpen(): bool, die den aktuellen Status zurückgibt
- Eine private boolesche Eigenschaft
main.php— Binden Sie die FileProcessor-Datei ein. Sie erhalten eine Eingabe: einen Dateinamen.Erstellen Sie einen
FileProcessorund verwenden Sie einetry-catch-finally-Struktur, um:- Im
try-Block: Rufen Sieopen()mit dem Dateinamen auf und rufen Sie anschließendprocess()auf - Fangen Sie zuerst
FileExceptionab und geben Sie"File error: [message]"aus - Fangen Sie
RuntimeExceptionab und geben Sie"Runtime error: [message]"aus - Im
finally-Block: Prüfen Sie mitisOpen(), ob die Datei geöffnet ist, und falls ja, rufen Sieclose()auf. Geben Sie anschließend"Cleanup complete"aus
- Im
Der finally-Block stellt sicher, dass die Bereinigung erfolgt, unabhängig davon, ob die Operationen erfolgreich waren oder fehlgeschlagen sind. Dieses Muster ist essenziell für die Verwaltung von Ressourcen wie Dateien, Datenbankverbindungen oder Netzwerk-Sockets, bei denen eine Bereinigung unabhängig vom Verlauf der Verarbeitung stattfinden muss.
Spickzettel
Verwenden Sie try-catch-finally, um Ausnahmen elegant zu behandeln und sicherzustellen, dass Bereinigungscode immer ausgeführt wird:
<?php
try {
// code that might throw an exception
} catch (ExceptionType $e) {
// handle the exception
echo $e->getMessage();
}
Fangen Sie mehrere Ausnahmetypen mit separaten catch-Blöcken ab. Platzieren Sie spezifischere Ausnahmen zuerst:
<?php
try {
// risky code
} catch (InvalidArgumentException $e) {
echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
echo "Something went wrong: " . $e->getMessage();
}
Der finally-Block wird unabhängig davon ausgeführt, ob eine Ausnahme ausgelöst oder abgefangen wurde, was ihn ideal für Bereinigungsoperationen macht:
<?php
try {
// attempt operation
} catch (Exception $e) {
// handle error
} finally {
// cleanup code runs always
}
Probier es selbst
<?php
require_once 'FileProcessor.php';
// Eingabe lesen
$filename = trim(fgets(STDIN));
// TODO: Erstellen Sie eine FileProcessor-Instanz
// TODO: Verwenden Sie eine try-catch-finally-Struktur:
// - Im try-Block: Rufen Sie open() mit dem Dateinamen auf, rufen Sie dann process() auf
// - Fangen Sie zuerst FileException ab und geben Sie "File error: [message]" aus
// - Fangen Sie RuntimeException ab und geben Sie "Runtime error: [message]" aus
// - Im finally-Block: Prüfen Sie mit isOpen(), ob die Datei offen ist, falls ja, rufen Sie close() auf
// Geben Sie dann "Cleanup complete" aus
?>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 die OOPKlassen vs. ObjekteDas $this-SchlüsselwortMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick - Einfacher Taschenrechner4Vererbung
Grundlagen der VererbungDas parent:: SchlüsselwortMethoden überschreibenDas final SchlüsselwortAbstrakte KlassenZusammenfassung – Mitarbeiter-Hierarchie7Kapselung
Public, Protected, PrivateZugriffsmodifikatoren im DetailGetter und SetterInformation HidingConstructor Promotion (8.0)Zusammenfassung – Studentenverwaltungssystem2Namensräume & Autoloading
Einführung in NamensräumeDas use-SchlüsselwortPSR-4 Autoloading-StandardComposer AutoloaderZusammenfassung – Organisiertes Projekt5Interfaces & Verträge
Einführung in InterfacesInterfaces implementierenMehrfache Interface-ImplementierungInterface vs. Abstrakte KlasseType Hinting mit InterfacesZusammenfassung – Formen-Rechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objekt-Klonen__serialize & __unserializeZusammenfassung - Eigene Collection11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenEigene Exception-HierarchieTry, Catch, FinallyZusammenfassung - Formular-Validator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klasseneigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenReadonly-Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphismus
Method Overriding erneut betrachtetPolymorphismus über InterfacesType Hinting & Union TypesLate Static BindingZusammenfassung – Payment Processor9Traits
Einführung in TraitsVerwendung mehrerer TraitsKonfliktlösung bei TraitsAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung