Menu
Coddy logo textTech

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 zero

Sie 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 complete

Der 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.

challenge icon

Aufgabe

Einfach

Lassen 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 benutzerdefinierte FileException-Klasse, die Exception erweitert. Diese wird dateibezogene Fehler in Ihrem System repräsentieren.
  • FileProcessor.php — Erstellen Sie eine FileProcessor-Klasse, die Dateioperationen simuliert. Binden Sie die FileException-Datei ein. Ihre Klasse sollte Folgendes enthalten:
    • Eine private boolesche Eigenschaft $isOpen, die mit false initialisiert wird
    • Eine Methode open(string $filename): void, die $isOpen auf true setzt und "Opening: [filename]" ausgibt. Wenn der Dateiname "invalid.txt" lautet, werfen Sie eine FileException mit der Nachricht "Cannot open file"
    • Eine Methode process(): void, die "Processing file..." ausgibt. Wenn $isOpen den Wert false hat, werfen Sie eine RuntimeException mit der Nachricht "File not open"
    • Eine Methode close(): void, die $isOpen auf false setzt und "File closed" ausgibt
    • Eine Methode isOpen(): bool, die den aktuellen Status zurückgibt
  • main.php — Binden Sie die FileProcessor-Datei ein. Sie erhalten eine Eingabe: einen Dateinamen.

    Erstellen Sie einen FileProcessor und verwenden Sie eine try-catch-finally-Struktur, um:

    • Im try-Block: Rufen Sie open() mit dem Dateinamen auf und rufen Sie anschließend 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 geöffnet ist, und falls ja, rufen Sie close() auf. Geben Sie anschließend "Cleanup complete" aus

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

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