Menu
Coddy logo textTech

Try, Catch, Finally

Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 68 z 91.

Teraz, gdy wiesz, jak tworzyć i zgłaszać wyjątki, musisz nauczyć się je przechwytywać. Struktura try-catch-finally pozwala elegancko obsługiwać wyjątki, zamiast pozwalać im powodować awarię aplikacji.

Umieść kod, który może zgłosić wyjątek, w bloku try, a następnie obsłuż wyjątek w bloku catch:

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

Wynik:

Error: Cannot divide by zero

Możesz przechwytywać różne typy wyjątków za pomocą wielu bloków catch. PHP sprawdza je po kolei, dlatego umieszczaj bardziej szczegółowe wyjątki wcześniej:

<?php
try {
    // ryzykowny kod
} catch (InvalidArgumentException $e) {
    echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something went wrong: " . $e->getMessage();
}

Blok finally wykonuje się niezależnie od tego, czy wyjątek został zgłoszony lub przechwycony. Doskonale nadaje się do zadań porządkowych, takich jak zamykanie połączeń:

<?php
try {
    echo "Attempting operation\n";
    throw new Exception("Failed");
} catch (Exception $e) {
    echo "Caught: " . $e->getMessage() . "\n";
} finally {
    echo "Cleanup complete";
}

Wynik:

Attempting operation
Caught: Failed
Cleanup complete

Blok finally wykonuje się nawet wtedy, gdy zwrócisz wartość z bloku try lub catch, dzięki czemu można na nim polegać przy niezbędnych operacjach porządkowych.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system przetwarzania plików, który pokazuje, jak try-catch-finally współpracują przy sprawnej obsłudze błędów i zapewnianiu, że czyszczenie zawsze zostanie wykonane.

Podzielisz kod na trzy pliki:

  • FileException.php: Utwórz własną klasę FileException, która rozszerza Exception. Będzie ona reprezentować błędy związane z plikami w twoim systemie.
  • FileProcessor.php: Utwórz klasę FileProcessor, która symuluje operacje na plikach. Dołącz plik FileException. Twoja klasa powinna zawierać:
    • Prywatną właściwość logiczną $isOpen, zainicjalizowaną wartością false
    • Metodę open(string $filename): void, która ustawia $isOpen na true i wyświetla "Opening: [filename]". Jeśli nazwa pliku to "invalid.txt", rzuć wyjątek FileException z komunikatem "Cannot open file"
    • Metodę process(): void, która wyświetla "Processing file...". Jeśli $isOpen ma wartość false, rzuć wyjątek RuntimeException z komunikatem "File not open"
    • Metodę close(): void, która ustawia $isOpen na false i wyświetla "File closed"
    • Metodę isOpen(): bool, która zwraca bieżący stan
  • main.php: Dołącz plik FileProcessor. Otrzymasz jedno wejście: nazwę pliku.

    Utwórz obiekt FileProcessor i użyj struktury try-catch-finally, aby:

    • W bloku try: wywołać open() z nazwą pliku, a następnie wywołać process()
    • Najpierw przechwycić FileException i wyświetlić "File error: [message]"
    • Przechwycić RuntimeException i wyświetlić "Runtime error: [message]"
    • W bloku finally: sprawdzić za pomocą isOpen(), czy plik jest otwarty, a jeśli tak, wywołać close(). Następnie wyświetlić "Cleanup complete"

Blok finally zapewnia wykonanie czyszczenia niezależnie od tego, czy operacje się powiodą, czy nie. Ten wzorzec jest niezbędny do zarządzania zasobami, takimi jak pliki, połączenia z bazą danych czy gniazda sieciowe, w przypadku których czyszczenie musi nastąpić niezależnie od tego, co wydarzy się podczas przetwarzania.

Spróbuj swoich sił

<?php
require_once 'FileProcessor.php';

// Odczytaj dane wejściowe
$filename = trim(fgets(STDIN));

// TODO: Utwórz instancję FileProcessor

// TODO: Użyj struktury try-catch-finally:
// - W bloku try: wywołaj open() z nazwą pliku, a następnie wywołaj process()
// - Najpierw przechwyć FileException i wypisz "File error: [message]"
// - Przechwyć RuntimeException i wypisz "Runtime error: [message]"
// - W bloku finally: sprawdź za pomocą isOpen(), czy plik jest otwarty; jeśli tak, wywołaj close()
//   Następnie wypisz "Cleanup complete"

?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online