Как обработать ошибки с помощью try/catch?php-15

Конструкция try/catch — это механизм обработки исключений (exceptions), который позволяет корректно реагировать на ошибки в процессе выполнения программы.

Базовый синтаксис

try {
    // Код, который может вызвать исключение
    $file = fopen("nonexistent.txt", "r");
    if (!$file) {
        throw new Exception("Файл не найден");
    }
} catch (Exception $e) {
    // Обработка исключения
    echo "Ошибка: " . $e->getMessage();
}

Компоненты обработки исключений

  1. try — блок кода, в котором могут возникнуть исключения
  2. throw — генерация исключения
  3. catch — блок обработки исключения определенного типа
  4. finally (опционально) — код, который выполнится в любом случае

Множественные блоки catch

Можно перехватывать разные типы исключений:

try {
    // Код, который может вызвать разные исключения
} catch (InvalidArgumentException $e) {
    // Обработка неверного аргумента
} catch (RuntimeException $e) {
    // Обработка ошибки выполнения
} catch (Exception $e) {
    // Общая обработка всех остальных исключений
}

Блок finally

Выполняется всегда, независимо от того, было исключение или нет:

$resource = null;
try {
    $resource = openResource();
    // Работа с ресурсом
} catch (Exception $e) {
    logError($e->getMessage());
} finally {
    if ($resource !== null) {
        closeResource($resource);
    }
}

Создание собственных исключений

class DatabaseException extends Exception {
    protected $query;

    public function __construct($message, $query, $code = 0, Exception $previous = null) {
        $this->query = $query;
        parent::__construct($message, $code, $previous);
    }

    public function getQuery() {
        return $this->query;
    }
}

try {
    throw new DatabaseException("Connection failed", "SELECT * FROM users");
} catch (DatabaseException $e) {
    echo $e->getMessage(); // "Connection failed"
    echo $e->getQuery();   // "SELECT * FROM users"
}

Лучшие практики

  1. Ловите конкретные исключения, а не общий Exception
  2. Не используйте try/catch для контроля потока выполнения — только для обработки ошибок
  3. Логируйте исключения перед их перехватом
  4. Избегайте пустых catch-блоков — это скрывает ошибки
  5. Используйте finally для освобождения ресурсов

Пример обработки PDO исключений

try {
    $pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("INSERT INTO users (name) VALUES (?)");
    $stmt->execute([$name]);
} catch (PDOException $e) {
    error_log("Database error: " . $e->getMessage());
    throw new Exception("Service unavailable");
}

Обработка нескольких исключений в одном блоке

try {
    // Код, который может вызвать исключения
} catch (FirstException | SecondException $e) {
    // Обработка обоих типов исключений
}

Резюмируем:

try/catch в PHP — это мощный механизм для обработки исключительных ситуаций. Он позволяет отделить нормальный поток выполнения программы от обработки ошибок, делает код более надежным и поддерживаемым. Правильное использование исключений значительно улучшает стабильность приложений.