Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Исключения

Программа не всегда может выполнить то, о чём её просят: файл не найден, данные некорректны, деление на ноль. Исключения — это способ сообщить о такой ситуации и обработать её в подходящем месте.

throw и try/catch

Оператор throw «бросает» исключение: выполнение функции прерывается. Поймать его можно блоком catch, а код, в котором оно может возникнуть, помещают в try:

<?php
 
function divide(int $a, int $b): float
{
    if ($b === 0) {
        throw new InvalidArgumentException('Делить на ноль нельзя');
    }
 
    return $a / $b;
}
 
try {
    echo divide(10, 2), "\n";
    echo divide(1, 0);
} catch (InvalidArgumentException $e) {
    echo 'Ошибка: ', $e->getMessage();
}

Первый вызов сработал, второй бросил исключение, и управление сразу перешло в catch. Метод getMessage() возвращает текст, переданный при создании исключения.

Что будет без catch

Если исключение никто не поймал, программа останавливается с сообщением Fatal error: Uncaught .... Поэтому исключение должно быть обработано хотя бы на самом верхнем уровне программы.

finally

Блок finally выполняется всегда — и после успешного try, и после catch. В нём освобождают ресурсы: закрывают файлы и соединения.

<?php
 
try {
    echo "Открываем файл\n";
    throw new RuntimeException('Сбой чтения');
} catch (RuntimeException $e) {
    echo $e->getMessage(), "\n";
} finally {
    echo 'Закрываем файл';
}

Свои исключения

Исключение — это объект класса, поэтому можно создавать свои, наследуя Exception. Отдельный класс позволяет ловить именно эту ошибку и не путать её с другими:

<?php
 
class NotEnoughMoney extends Exception {}
 
function pay(int $balance, int $price): int
{
    if ($price > $balance) {
        throw new NotEnoughMoney('Не хватает ' . ($price - $balance));
    }
 
    return $balance - $price;
}
 
try {
    pay(100, 250);
} catch (NotEnoughMoney $e) {
    echo $e->getMessage(); // Не хватает 150
}

Встроенные ошибки

PHP сам бросает исключения при некоторых ошибках — например, при целочисленном делении на ноль или передаче значения неподходящего типа:

<?php
 
try {
    echo intdiv(1, 0);
} catch (DivisionByZeroError $e) {
    echo $e->getMessage(); // Division by zero
}

Ошибки языка наследуются от Error, а обычные исключения — от Exception. Общий для них тип — Throwable.

Частая ошибка

Пустой блок catch «проглатывает» ошибку: программа продолжает работать с неверными данными, а найти причину потом очень трудно. Ловите только те исключения, которые умеете обработать, и никогда не оставляйте catch пустым.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.