🧱 Суть

В PHP ошибки и исключения используются для обработки ситуаций, когда программа не может продолжить нормальное выполнение.

Исключение (Exception) – это объект, который сообщает о возникшей проблеме и передаёт управление в блок обработки.

Пример:

try {
    $result = divide(10, 0);
} catch (Exception $e) {
    echo $e->getMessage();
}

Вместо аварийного завершения программа может корректно обработать ошибку.

📦 Проблема

1. Ошибки могут остановить выполнение программы

Например:

$file = fopen("missing.txt", "r");

Если файла нет – возникает проблема.

2. Смешивание бизнес-логики и обработки ошибок

Плохой вариант:

if (!$user) {
    echo "Ошибка";
    exit;
}

Код начинает содержать много проверок и становится сложнее поддерживать.

3. Непредсказуемое поведение при ошибках

Без единого подхода сложно понять:

  • где ошибка возникла
  • кто её обработает
  • что увидит пользователь

✅ Решение

Использовать исключения:

  • выбрасывать ошибку через throw
  • перехватывать через try/catch
  • передавать информацию об ошибке через объект исключения

💻 Код

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

try {
    // код, который может вызвать ошибку
} catch (Exception $e) {
    // обработка ошибки
}

Пример:

try {
    $result = 10 / 0;
} catch (Exception $e) {
    echo "Произошла ошибка";
}

Выбрасывание исключений (throw)

Исключение создаётся вручную:

throw new Exception("Что-то пошло не так");

Пример:

function divide($a, $b)
{
    if ($b === 0) {
        throw new Exception("Деление на ноль");
    }
 
    return $a / $b;
}

Использование:

try {
    echo divide(10, 0);
} catch (Exception $e) {
    echo $e->getMessage();
}

Результат:

Деление на ноль

Объект исключения

Исключение содержит информацию об ошибке:

catch (Exception $e) {
    echo $e->getMessage();
}

Основные методы:

МетодНазначение
getMessage()текст ошибки
getCode()код ошибки
getFile()файл, где произошла ошибка
getLine()строка с ошибкой
getTrace()стек вызовов

Несколько блоков catch

Можно обрабатывать разные типы ошибок:

try {
    // код
}
catch (InvalidArgumentException $e) {
    echo "Неверный аргумент";
}
catch (Exception $e) {
    echo "Общая ошибка";
}

Более конкретные исключения ставятся выше.

Блок finally

finally выполняется всегда:

try {
    echo "Попытка";
}
catch (Exception $e) {
    echo "Ошибка";
}
finally {
    echo "Очистка";
}

Используется для:

  • закрытия файлов
  • освобождения ресурсов
  • завершения операций

Типы исключений

PHP имеет встроенные классы исключений:

Exception
ErrorException
RuntimeException
LogicException
InvalidArgumentException

Пример:

function setAge($age)
{
    if ($age < 0) {
        throw new InvalidArgumentException(
            "Возраст не может быть отрицательным"
        );
    }
}

Throwable: ошибки и исключения

В PHP 7+ существует общий интерфейс:

Throwable

Он объединяет:

  • Exception
  • Error

Можно перехватить оба типа:

try {
    // код
}
catch (Throwable $e) {
    echo $e->getMessage();
}

Свои классы исключений

В больших проектах создают собственные ошибки:

class UserNotFoundException extends Exception
{
}

Использование:

throw new UserNotFoundException(
    "Пользователь не найден"
);

Плюсы:

  • проще отличать ошибки
  • удобнее обрабатывать разные сценарии
  • код становится понятнее

Ошибки PHP (Error) и исключения (Exception)

Важно различать:

Exception
Ошибки логики приложения:

throw new Exception("Нет доступа");

Error
Ошибки самого PHP:

undefined function()

Обычно разработчик не создаёт Error вручную.

Логирование ошибок

В реальных приложениях ошибки записывают в лог:

catch (Throwable $e) {
    error_log($e->getMessage());
}

Пользователю обычно показывают общее сообщение:

Произошла ошибка. Попробуйте позже.

А детали сохраняют для разработчиков.

🎯 Вывод

  • исключения позволяют отделить ошибку от основной логики
  • throw создаёт исключение
  • try/catch перехватывает и обрабатывает ошибки
  • finally выполняет обязательный код после попытки
  • Throwable позволяет ловить и Exception, и Error
  • в больших проектах используют собственные классы исключений
  • ошибки нужно логировать, а не показывать пользователю напрямую

🔗 Связано