English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В этом руководстве вы узнаете, как вызывать и перехватывать исключительные ситуации в PHP.
являются сигналом о возникновении某种 исключительного события или ошибки. Исключительные ситуации могут возникать по множеству причин, таких как, например, сбой подключения или запроса к базе данных, файл, к которому вы пытаетесь получить доступ, не существует и т.д.
PHP предоставляет мощный механизм обработки исключительных ситуаций, который позволяет优雅 образом обрабатывать исключительные ситуации. В отличие от традиционногообработка ошибоксистемы, напротив, обработка исключительных ситуаций является методом обработки ошибокориентированного на объектыпозволяет предоставлять более конкретные и гибкие формы отчетов об ошибках. Модель исключительных ситуаций была最早 введена в PHP 5.
В методе, основанном на исключительных ситуациях, код программы пишется в блоке try, и когда во время выполнения кода в блоке try возникает исключительная ситуация, можно использовать оператор throw для вызова исключительной ситуации. Затем её можно перехватить и обработать одним или несколькими блоками catch.
Ниже приведен пример того, как работает обработка исключительных ситуаций:
<?php function division($dividend, $divisor){ // если делитель равен нулю, то выбрасывается исключительная ситуация if($divisor == 0){ throw new Exception('Деление на ноль.'); } $quotient = $dividend / $divisor; echo "<p>$dividend / $divisor = $quotient</p>"; } } try{ division(10, 2); division(30, -4); division(15, 0); // если возникает исключительная ситуация,后面的行将不会执行 echo '<p>Все операции выполнены успешно.</p>'; } // обработка исключительных ситуаций echo "<p>Захваченная исключительная ситуация: " . $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 также предоставляются методы getCode(), getFile(), getLine() и getTraceAsString(), которые можно использовать для генерации детальной информации о отладке.
<?php //Отключение-default отчеты об ошибках error_reporting(0); try{ $file = "somefile.txt"; //Попытка открыть файл $handle = fopen($file, "r"); if (!$handle) { throw new Exception("Не удалось открыть файл!", 5); } //Попытка чтения содержимого файла $content = fread($handle, filesize($file)); if (!$content) { throw new Exception("Не удалось прочитать файл!", 10); } //Закрытие дескриптора файла fclose($handle); //Отображение содержимого файла echo $content; } echo "<h3>Захвачено исключение!</h3>"; echo "<p>Сообщение об ошибке: " . $e->getMessage() . "</p>"; echo "<p>Файл: " . $e->getFile() . "</p>"; echo "<p>Строка: " . $e->getLine() . "</p>"; echo "<p>Код ошибки: " . $e->getCode() . "</p>"; echo "<p>Trace: " . $e->getTraceAsString() . "</p>"; } ?>
Конструктор исключения может выбирать принимать сообщение об исключении и код исключения. Хотя сообщение об исключении обычно используется для отображения общей информации о причине ошибки, код исключения может использоваться для классификации ошибок. Позднее предоставленный код исключения можно извлечь с помощью метода getCode() класса Exception.
Совет:Исключения применяются только к特殊情况м; они не должны использоваться для определения нормального потока приложения, например, для перехода к другому месту в скрипте. Это может негативно повлиять на производительность приложения.
Вы можете даже определить свой пользовательский обработчик исключений для обработки различных типов исключений по-разному. Это позволяет использовать отдельный блок catch для каждого типа исключения.
Вы можете расширить класс Exception для создания пользовательских исключений, так как Exception является базовым классом для всех исключений. Пользовательские исключения наследуют все свойства и методы класса PHP Exception. Вы также можете добавить свои собственные методы в пользовательский класс исключений. Давайте посмотрим на следующий пример:
<?php // Расширение класса Exception class EmptyEmailException extends Exception {} class InvalidEmailException extends Exception {} $email = "[email protected]"; try{ // Если электронная почта пуста, то выбросить исключение if($email == ""){ throw new EmptyEmailException("<p>Пожалуйста, введите ваш адрес электронной почты!</p>"); } // Если электронная почта недействительна, то выбросить исключение if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) { throw new InvalidEmailException("<p><b>$email</b> не является действительным адресом электронной почты!</p>"); } // Если электронная почта действительна, то отобразить успешное сообщение echo "<p>Успешно: проверка электронной почты успешна.</p>"; catch(EmptyEmailException $e){ echo $e->getMessage(); catch(InvalidEmailException $e){ echo $e->getMessage(); } ?>
В примере выше мы создали два новых класса исключений, произошедших от базового класса Exception:EmptyEmailExceptionиInvalidEmailException. Используются несколько блоков перехвата для отображения различных сообщений об ошибках, в зависимости от типа возникшего исключения.
Поскольку эти пользовательские классы исключений наследуют атрибуты и методы класса Exception, мы можем использовать методы класса исключения, такие как getMessage(), getLine(), getFile() и т.д., для извлечения информации об ошибке объекта исключения.
Как обсуждалось в начале этой главы, если не捕获 исключение, PHP генерирует критическую ошибку с сообщением "Не捕获ленное исключение ...". Это сообщение об ошибке может содержать конфиденциальную информацию, такую как имя файла и номер строки, где возникла проблема. Если вы не хотите公开此类 информацию пользователю, вы можете создать пользовательскую функцию и зарегистрировать ее в функции set_exception_handler() для обработки всех не捕获енных исключений.
<?php function handleUncaughtException($e){ // отображать пользователю общее сообщение об ошибке echo "Ой! Something went wrong. Please try again, if the problem persists, please contact us."; // конструировать строку ошибки $error = "Не捕获ленное исключение: " . $message = date("Y-m-d H:i:s - "); $error .= $e->getMessage() . " в файле " . $e->getFile() . " на строке " . $e->getLine() . "\n"; // записывать детальную информацию об ошибке в файл error_log($error, 3, "var/log/exceptionLog.log"); } // регистрация пользовательского обработчика исключений set_exception_handler("handleUncaughtException"); // выбрасывать исключение throw new Exception("Testing Exception!"); ?>
Внимание:Не捕获ленные исключения всегда приводят к завершению скрипта. Поэтому, если вы хотите, чтобы скрипт продолжал выполняться после места возникновения исключения, каждый блок try должен иметь по крайней мере один соответствующий блок catch.