Menu
Coddy logo textTech

Try, Catch, Finally

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 68 из 91.

Теперь, когда ты знаешь, как создавать и выбрасывать исключения, тебе нужно научиться их catch. Структура try-catch-finally позволяет корректно обрабатывать исключения, вместо того чтобы позволить им привести к сбою приложения.

Поместите код, который может вызвать исключение, в блок try, затем обработайте исключение в блоке 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();
}

Вывод:

Error: Cannot divide by zero

Вы можете обрабатывать разные типы исключений с помощью нескольких блоков catch. PHP проверяет их по порядку, поэтому размещайте более специфичные исключения первыми:

<?php
try {
    // рискованный код
} catch (InvalidArgumentException $e) {
    echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something went wrong: " . $e->getMessage();
}

Блок finally выполняется независимо от того, было ли выброшено или перехвачено исключение. Он идеально подходит для задач cleanup, таких как закрытие соединений:

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

Вывод:

Attempting operation
Caught: Failed
Cleanup complete

Блок finally выполняется, даже если вы возвращаете значение из блоков try или catch, что делает его надёжным для важных операций cleanup.

challenge icon

Задание

Легко

Давайте создадим систему обработки file, которая демонстрирует, как try-catch-finally совместно обрабатывает errors, гарантируя, что очистка always выполняется.

Вы организуете код в трёх files:

  • FileException.php: Create пользовательский класс FileException, который extends Exception. Он будет представлять ошибки, связанные с file, в вашей системе.
  • FileProcessor.php: Create класс FileProcessor, имитирующий операции с file. Подключите file FileException. В вашем классе должны быть:
    • Приватное свойство типа boolean $isOpen, initialized значением false
    • Метод open(string $filename): void, который устанавливает $isOpen в значение true и выводит "Opening: [filename]". Если имя file равно "invalid.txt", выбросьте FileException с сообщением "Cannot open file"
    • Метод process(): void, который выводит "Processing file...". Если $isOpen равно false, выбросьте RuntimeException с сообщением "File not open"
    • Метод close(): void, который устанавливает $isOpen в значение false и выводит "File closed"
    • Метод isOpen(): bool, который возвращает current состояние
  • main.php: Подключите file FileProcessor. Вы получите один input: имя file.

    Create объект FileProcessor и используйте структуру try-catch-finally, чтобы:

    • В блоке try: вызовите open() с именем file, затем вызовите process()
    • Сначала Catch FileException и выведите "File error: [message]"
    • Catch RuntimeException и выведите "Runtime error: [message]"
    • В блоке finally: проверьте, открыт ли file, используя isOpen(), и, если да, вызовите close(). Затем выведите "Cleanup complete"

Блок finally гарантирует, что очистка произойдёт независимо от того, завершатся ли операции успешно или завершатся с ошибкой. Этот шаблон необходим для управления такими ресурсами, как files, подключения к базам данных или сетевые сокеты, где очистка должна выполняться независимо от происходящего во время обработки.

Попробуйте сами

<?php
require_once 'FileProcessor.php';

// Прочитать ввод
$filename = trim(fgets(STDIN));

// TODO: Создать экземпляр FileProcessor

// TODO: Использовать структуру try-catch-finally:
// - В блоке try: вызвать open() с filename, затем вызвать process()
// - Сначала перехватить FileException и вывести "File error: [message]"
// - Перехватить RuntimeException и вывести "Runtime error: [message]"
// - В блоке finally: проверить, открыт ли файл с помощью isOpen(), если да, вызвать close()
//   Then print "Cleanup complete"

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор PHP