Обработка исключений (Exception Handling) — это сигнал, указывающий на какое-то исключительное событие или ошибку. Исключения могут быть вызваны разными причинами, например, сбой подключения к базе данных или запроса, файл, к которому вы пытаетесь получить доступ, не существует и так далее.

PHP предоставляет мощный механизм обработки исключений, который позволяет их изящно обрабатывать. В отличие от традиционной системы обработки ошибок PHP, обработка исключений — это объектно-ориентированный подход к обработке ошибок, который обеспечивает более контролируемую и гибкую форму сообщения об ошибках. Модель исключений была впервые представлена в PHP 5.

Использование операторов Throw and Try…Catch

В подходе, основанном на исключениях, программный код записывается в блоке try, исключение может быть создано с помощью оператора throw, когда во время выполнения кода в блоке try возникает исключительное событие. Затем он перехватывается и разрешается одним или несколькими блоками catch.

В следующем примере показано, как работает обработка исключений:

<?php
function division($dividend, $divisor){
    // Выбрасываем исключение, если делитель равен нулю
    if($divisor == 0){
        throw new Exception('Division by zero.');
    } else{
        $quotient = $dividend / $divisor;
        echo "<p>$dividend / $divisor = $quotient</p>";
    }
}
 
try{
    division(10, 2);
    division(30, -4);
    division(15, 0);
    
    // Если выбрано исключение, следующая строка не будет выполняться
    echo '<p>All divisions performed successfully.</p>';
} catch(Exception $e){
    // Обработка исключений
    echo "<p>Caught exception: " . $e->getMessage() . "</p>";
}
 
// Продолжаем выполнение
echo "<p>Hello World!</p>";
?>

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

  • Функция division() в приведенном выше примере проверяет, равен ли делитель нулю. Если это так, то с помощью оператора throw PHP генерируется исключение. В противном случае эта функция выполняет деление с использованием заданных чисел и отображает результат.
  • Позже в блоке try вызывается функция division() с разными аргументами. Если при выполнении кода в блоке try генерируется исключение, PHP останавливает выполнение в этой точке и пытается найти соответствующий блок catch. Если он найден, выполняется код в этом блоке catch, если нет, генерируется фатальная ошибка.
  • Блок catch обычно перехватывает исключение, созданное в блоке try, и создает объект ($e), содержащий информацию об исключении. Сообщение об ошибке от этого объекта можно получить с помощью метода getMessage().

PHP-класс Exception также предоставляет методы getCode(), getFile(), getLine() и getTraceAsString(), которые можно использовать для генерации подробной отладочной информации.

<?php
// Отключаем отчет об ошибках по умолчанию
error_reporting(0);
 
try{
    $file = "somefile.txt";
    
    // Попытка открыть файл
    $handle = fopen($file, "r");
    if(!$handle){
        throw new Exception("Cannot open the file!", 5);
    }
    
    // Попытка прочитать содержимое файла
    $content = fread($handle, filesize($file));
    if(!$content){
        throw new Exception("Could not read file!", 10);
    }
    
    // Закрытие дескриптора файла
    fclose($handle);
    
    // Показываем содержимое файла
    echo $content;
} catch(Exception $e){
    echo "<h3>Caught Exception!</h3>";
    echo "<p>Error message: " . $e->getMessage() . "</p>";    
    echo "<p>File: " . $e->getFile() . "</p>";
    echo "<p>Line: " . $e->getLine() . "</p>";
    echo "<p>Error code: " . $e->getCode() . "</p>";
    echo "<p>Trace: " . $e->getTraceAsString() . "</p>";
}
?>

Конструктор Exception дополнительно принимает сообщение об исключении и код исключения. Хотя сообщение об исключении обычно используется для отображения общей информации о том, что пошло не так, код исключения можно использовать для классификации ошибок. Предоставленный код исключения можно получить позже с помощью метода Exception getCode().

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

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

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

Вы можете определить настраиваемое исключение, расширив класс Exception, потому что Exception является базовым классом для всех исключений. Пользовательский класс исключения наследует все свойства и методы от класса исключений PHP. Вы также можете добавить свои собственные методы в собственный класс исключений. Давайте посмотрим на следующий пример:

<?php
// Расширение класса Exception
class EmptyEmailException extends Exception {}
class InvalidEmailException extends Exception {}
 
$email = "someuser@example..com";
 
try{
    // Проверяем, если адрес электронной почты пуст
    if($email == ""){
        throw new EmptyEmailException("<p>Please enter your E-mail address!</p>");
    }
    
    // Проверяем, если адрес электронной почты недействителен
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {           
        throw new InvalidEmailException("<p><b>$email</b> is not a valid E-mail address!</p>");
    }
    
    // Отображаем сообщение об успешном завершении, если адрес электронной почты действителен
    echo "<p>SUCCESS: Email validation successful.</p>";
} catch(EmptyEmailException $e){
    echo $e->getMessage();
} catch(InvalidEmailException $e){
    echo $e->getMessage();
}
?>

В приведенном выше примере мы создали два новых класса исключений: EmptyEmailException, и InvalidEmailException из базового класса Exception. Несколько блоков catch используются для отображения различных сообщений об ошибках в зависимости от типа сгенерированного исключения.

Поскольку эти настраиваемые классы исключений наследуют свойства и методы класса Exception, мы можем использовать методы класса Exception, такие как getMessage(), getLine(), getFile() и т. д., для извлечения информации об ошибке из объекта исключения.

Установка глобального обработчика исключений

Как мы уже обсуждали ранее в этой главе, если исключение не перехвачено, PHP генерирует фатальную ошибку с сообщением Uncaught Exception …. Это сообщение об ошибке может содержать конфиденциальную информацию, такую как имя файла и номер строки, в которой возникает проблема. Если вы не хотите предоставлять такую информацию пользователю, вы можете создать собственную функцию и зарегистрировать ее с помощью функции set_exception_handler() для обработки всех неперехваченных исключений.

<?php
function handleUncaughtException($e){
    // Отображаем общее сообщение об ошибке для пользователя
    echo "Opps! Something went wrong. Please try again, or contact us if the problem persists.";
    
    // Создаем строку ошибки
    $error = "Uncaught Exception: " . $message = date("Y-m-d H:i:s - ");
    $error .= $e->getMessage() . " in file " . $e->getFile() . " on line " . $e->getLine() . "\n";
    
    // Записываем сведения об ошибке в файл
    error_log($error, 3, "var/log/exceptionLog.log");
}
 
// Регистрируем пользовательский обработчик исключений
set_exception_handler("handleUncaughtException");
 
// Исключение
throw new Exception("Testing Exception!");
?>

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

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 5 / 5. Количество оценок: 1

Оценок пока нет. Поставьте оценку первым.