Как отловить все ошибки php
Перейти к содержимому

Как отловить все ошибки php

  • автор:

Ошибки и их обработка

PDO предлагает на выбор 3 стратегии обработки ошибок в зависимости от вашего стиля разработки приложений.

  • PDO::ERRMODE_SILENT До PHP 8.0.0, это был режим по умолчанию. PDO просто предоставит вам код ошибки, который можно получить методами PDO::errorCode() и PDO::errorInfo() . Эти методы реализованы как в объектах запросов, так и в объектах баз данных. Если ошибка вызвана во время выполнения кода объекта запроса, нужно вызвать метод PDOStatement::errorCode() или PDOStatement::errorInfo() этого объекта. Если ошибка вызова объекта базы данных, нужно вызвать аналогичные методы у этого объекта.
  • PDO::ERRMODE_WARNING Помимо установки кода ошибки PDO выдаст обычное E_WARNING сообщение. Это может быть полезно при отладке или тестировании, когда нужно видеть, что произошло, но не нужно прерывать работу приложения.
  • PDO::ERRMODE_EXCEPTION Начиная с PHP 8.0.0 является режимом по умолчанию. Помимо задания кода ошибки PDO будет выбрасывать исключение PDOException , свойства которого будут отражать код ошибки и её описание. Этот режим также полезен при отладке, так как сразу известно, где в программе произошла ошибка. Это позволяет быстро локализовать и решить проблему. (Не забывайте, что если исключение является причиной завершения работы скрипта, все активные транзакции будут откачены.) Режим исключений также полезен, так как даёт возможность структурировать обработку ошибок более тщательно, нежели с обычными предупреждениями PHP, а также с меньшей вложенностью кода, чем в случае работы в тихом режиме с явной проверкой возвращаемых значений при каждом обращении к базе данных. Подробнее об исключениях в PHP смотрите в разделе Исключения.

PDO стандартизирован для работы со строковыми кодами ошибок SQL-92 SQLSTATE. Отдельные драйверы PDO могут задавать соответствия своих собственных кодов кодам SQLSTATE. Метод PDO::errorCode() возвращает одиночный код SQLSTATE. Если необходима специфичная информация об ошибке, PDO предлагает метод PDO::errorInfo() , который возвращает массив, содержащий код SQLSTATE, код ошибки драйвера, а также строку ошибки драйвера.

Пример #1 Создание PDO объекта и установка режима обработки ошибок

$dsn = ‘mysql:dbname=testdb;host=127.0.0.1’ ;
$user = ‘dbuser’ ;
$password = ‘dbpass’ ;

$dbh = new PDO ( $dsn , $user , $password );
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );

// PDO выбросит исключение PDOException (если таблица не существует)
$dbh -> query ( «SELECT wrongcolumn FROM wrongtable» );
?>

Результат выполнения приведённого примера:

Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testdb.wrongtable' doesn't exist in /tmp/pdo_test.php:10 Stack trace: #0 /tmp/pdo_test.php(10): PDO->query('SELECT wrongcol. ') #1 thrown in /tmp/pdo_test.php on line 10

Замечание:

Метод PDO::__construct() будет всегда бросать исключение PDOException , если соединение оборвалось, независимо от установленного значения PDO::ATTR_ERRMODE .

Пример #2 Создание экземпляра класса PDO и установка режима обработки ошибок в конструкторе

$dsn = ‘mysql:dbname=test;host=127.0.0.1’ ;
$user = ‘googleguy’ ;
$password = ‘googleguy’ ;

$dbh = new PDO ( $dsn , $user , $password , array( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_WARNING ));

// Следующий запрос приводит к ошибке уровня E_WARNING вместо исключения (когда таблица не существует)
$dbh -> query ( «SELECT wrongcolumn FROM wrongtable» );
?>

Результат выполнения приведённого примера:

Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.wrongtable' doesn't exist in /tmp/pdo_test.php on line 9

User Contributed Notes

There are no user contributed notes for this page.

  • PDO
    • Введение
    • Установка и настройка
    • Предопределённые константы
    • Подключения и управление подключениями
    • Транзакции и автоматическая фиксация изменений
    • Подготовленные запросы и хранимые процедуры
    • Ошибки и их обработка
    • Большие объекты (LOB)
    • PDO
    • PDOStatement
    • PDORow
    • PDOException
    • Драйверы PDO
    • Copyright © 2001-2024 The PHP Group
    • My PHP.net
    • Contact
    • Other PHP.net sites
    • Privacy policy

    Обработка исключений

    В процессе работы программы могут возникать различные ошибки, которые могут прервать работу программы. Например, рассмотрим следующую ситуацию:

    $a = 5; $b = 0; $result = $a / $b; echo $result; echo "Конец работы программы";

    Программа выводит результат деления. Поскольку делитель равен 0, а на ноль делить нельзя, то при выполнении деления программа завершится, и в браузере мы увидим что-то типа следующего:

    Fatal error: Uncaught DivisionByZeroError: Division by zero in D:\localhost\hello.php:11 Stack trace: #0 thrown in D:\localhost\hello.php on line 11

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

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

    Для обработки исключений в PHP применяется конструкция try-catch :

    try < // код, который может вызвать исключение >catch(Тип_исключения $ex) < // обработка исключения >

    Эта конструкция в общем варианте состоит из двух блоков — try и catch . В блок try помещается код, который потенциально может вызвать исключение. А в блоке catch помещается обработка возникшего исключения. Причем каждого типа исключения мы можем определить свою логику обработки. Конкретный тип исключения, который мы хотим обработать, указывается в круглых скобках после оператора catch :

    catch(Тип_исключения $ex)

    После названия типа указывается переменная этого типа (в данном случае $ex ), которая будет хранить информацию об исключении и которую мы можем использовать при обработке исключения.

    Если в блоке try при выполнении кода возникает ошибка, то блок try прекращает выполнение и передает управление блоку catch , который обрабатывает ошибку. А после завершения выполнения кода в блоке catch программа продолжает выполнять инструкции, которые размещены после блока catch .

    Если в блоке try при выполнении кода не возникает ошибок, то блок catch не выполняется, а после завершения блока try программа продолжает выполнять инструкции, которые размещены после блока catch .

    Например, обработаем ошибку с делением на ноль:

    try < // код, который может вызвать исключение $a = 5; $b = 0; $result = $a / $b; echo $result; >catch(DivisionByZeroError $ex) < // обработка исключения echo "Произошло исключение:
    "; echo $ex . "
    "; > echo "Конец работы программы";

    В данном случае код деления на ноль, поскольку он может потенциально вызвать ошибку, помещен в блок try .

    В блоке catch обрабатывается ошибка типа DivisionByZeroError , которая генерируется при делении на ноль. Вся обработка сводится к выводу информации на экран.

    В итоге при выполнении программа выведет следующее:

    Произошло исключение: DivisionByZeroError: Division by zero in D:\localhost\hello.php:14 Stack trace: #0 Конец работы программы

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

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

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

    Ошибки и исключения Error, Exception и Throwable в PHP

    Все типы делятся на две группы: собственно ошибки (класс Error ) и собственно исключения (класс Exception ). А от классов Error и Exception наследуются классы ошибок и исключений, которые описывают конкретные ситуации. Например, от класса Error наследуется класс ArithmeticError , который описывает ошибки, возникающие при выполнении арифметических операций. А от класса ArithmeticError наследуется класс DivisionByZeroError , который представляют ошибку при делении на ноль.

    Блок catch

    Конструкция try..catch позволяет определить несколько блоков catch — для обработки различных типов ошибок и исключений:

    try < $result = 5 / 0; echo $result; >catch(ParseError $p) < echo "Произошла ошибка парсинга"; >catch(DivisionByZeroError $d)

    При возникновении ошибки будет для ее обработки будет выбираться тот блок catch , который соответствует вошникшей ошибки. Так, в данном случае при делении на ноль будет выполняться второй блок catch .

    Если бы в блоке try возникла бы ошибка, которая бы не соответствовала типам из блоков catch (в данном случае — типам DivisionByZeroError и ParseError), то такая ошибка не была бы обработана, и соответственно программа бы аварийно завершила свое выполнение.

    Блоки catch с более конкретными типами ошибок и исключений должны идти в начале, а более с более общими типа — в конце:

    try < $result = 5 / 0; echo $result; >catch(DivisionByZeroError $ex) < echo "На ноль делить нельзя"; >catch(ArithmeticError $ex) < echo "Ошибка при выполнении арифметической операции"; >catch(Error $ex) < echo "Произошла ошибка"; >catch(Throwable $ex)

    Класс DivisionByZeroError унаследован от ArithmeticError, который, в свою очередь, унаследован от Error, реализующего интерфейс Throwable. Поэтому класс DivisionByZeroError представляет более конкретный тип и представляемые им ошибки должны обрабатываться в первую очередь. А тип Throwable представляет наиболее общий тип, так как ему соответствуют все возможные ошибки и исключения, поэтому блоки catch с таким типом должны идти в конце.

    В данном случае опять же в блоке try происходит ошибка деления на ноль. Но этой ошибке соответствуют все четыре блока catch . Для обработки PHP будет выбирать первый попавшийся, который соответствует типу ошибки. В данном случае это блок для обработки ошибки типа DivisionByZeroError.

    Если нам надо обрабатывать в принципе все ошибки и исключения, то мы можем определить только обработку общего для всех них типа Throwable:

    try < $result = 5 / 0; echo $result; >catch(Throwable $ex)

    Начиная с версии PHP 8.0 в блоке catch можно просто указать тип обрабатываемого исключения, не определяя переменную:

    catch(DivisionByZeroError)

    Получение информации об ошибках и исключениях

    Интерфейс Throwable предоставляет ряд методов, которые позволяют получить некоторую информацию о возникшем исключении:

    • getMessage() : возвращает сообщение об ошибке
    • getCode() : возвращает код исключения
    • getFile() : возвращает название файла, в котором возникла ошибка
    • getLine() : возвращает номер строки, в которой возникла ошибка
    • getTrace() : возвращает трассировку стека
    • getTraceAsString() : возвращает трассировку стека в виде строки

    Применим некоторые из этих методов:

    try < $result = 5 / 0; echo $result; >catch(DivisionByZeroError $ex) < echo "Сообщение об ошибке: " . $ex->getMessage() . "
    "; echo "Файл: " . $ex->getFile() . "
    "; echo "Номер строки: " . $ex->getLine() . "
    "; >
    Сообщение об ошибке: Division by zero Файл: D:\localhost\hello.php Номер строки: 11

    Блок finally

    Конструкция try..catch также может определять блок finally . Этот блок выполняется в конце — после блока try и catch вне зависимости, возникла или нет ошибка. Нередко блок finally используется для закрытия ресурсов, которые применяются в блоке try.

    try < $result = 5 / 0; echo $result . "
    "; > catch(Throwable $ex) < echo "Ошибка при выполнении программы
    "; > finally < echo "Блок finally
    "; > echo "Конец работы программы";
    Ошибка при выполнении программы Блок finally Конец работы программы

    Конструкция try..catch..finally может содержать либо все три блока, либо только два блока try и либо блок catch , либо блок finally .

    Как настроить отображение ошибок в PHP

    В этом руководстве мы расскажем о различных способах того, как в PHP включить вывод ошибок. Мы также обсудим, как записывать ошибки в журнал (лог).

    Как быстро показать все ошибки PHP

    Самый быстрый способ отобразить все ошибки и предупреждения php — добавить эти строки в файл PHP:

    ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); 

    Что именно делают эти строки?

    Функция ini_set попытается переопределить конфигурацию, найденную в вашем ini-файле PHP.

    Display_errors и display_startup_errors — это только две из доступных директив. Директива display_errors определяет, будут ли ошибки отображаться для пользователя. Обычно директива dispay_errors не должна использоваться для “боевого” режима работы сайта, а должна использоваться только для разработки.

    display_startup_errors — это отдельная директива, потому что display_errors не обрабатывает ошибки, которые будут встречаться во время запуска PHP. Список директив, которые могут быть переопределены функцией ini_set, находится в официальной документации .

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

    Отображение ошибок PHP через настройки в php.ini

    Если ошибки в браузере по-прежнему не отображаются, то добавьте директиву:

    display_errors = on 

    Директиву display_errors следует добавить в ini-файл PHP. Она отобразит все ошибки, включая синтаксические ошибки, которые невозможно отобразить, просто вызвав функцию ini_set в коде PHP.

    Актуальный INI-файл можно найти в выводе функции phpinfo (). Он помечен как “загруженный файл конфигурации” (“loaded configuration file”).

    Отображать ошибки PHP через настройки в .htaccess

    Включить или выключить отображение ошибок можно и с помощью файла .htaccess, расположенного в каталоге сайта.

    php_flag display_startup_errors on php_flag display_errors on 

    .htaccess также имеет директивы для display_startup_errors и display_errors.

    Вы можете настроить display_errors в .htaccess или в вашем файле PHP.ini. Однако многие хостинг-провайдеры не разрешают вам изменять ваш файл PHP.ini для включения display_errors.

    В файле .htaccess также можно включить настраиваемый журнал ошибок, если папка журнала или файл журнала доступны для записи. Файл журнала может быть относительным путем к месту расположения .htaccess или абсолютным путем, например /var/www/html/website/public/logs .

    php_value error_log logs/all_errors.log 

    Включить подробные предупреждения и уведомления

    Иногда предупреждения приводят к некоторым фатальным ошибкам в определенных условиях. Скрыть ошибки, но отображать только предупреждающие (warning) сообщения можно вот так:

    error_reporting(E_WARNING); 

    Для отображения предупреждений и уведомлений укажите «E_WARNING | E_NOTICE».

    Также можно указать E_ERROR, E_WARNING, E_PARSE и E_NOTICE в качестве аргументов. Чтобы сообщить обо всех ошибках, кроме уведомлений, укажите «E_ALL & ~ E_NOTICE», где E_ALL обозначает все возможные параметры функции error_reporting.

    Более подробно о функции error_reporting ()

    Функция сообщения об ошибках — это встроенная функция PHP, которая позволяет разработчикам контролировать, какие ошибки будут отображаться. Помните, что в PHP ini есть директива error_reporting, которая будет задана ​​этой функцией во время выполнения.

    error_reporting(0); 

    Для удаления всех ошибок, предупреждений, сообщений и уведомлений передайте в функцию error_reporting ноль. Можно сразу отключить сообщения отчетов в ini-файле PHP или в .htaccess:

    error_reporting(E_NOTICE); 

    PHP позволяет использовать переменные, даже если они не объявлены. Это не стандартная практика, поскольку необъявленные переменные будут вызывать проблемы для приложения, если они используются в циклах и условиях.

    Иногда это также происходит потому, что объявленная переменная имеет другое написание, чем переменная, используемая для условий или циклов. Когда E_NOTICE передается в функцию error_reporting, эти необъявленные переменные будут отображаться.

    error_reporting(E_ALL & ~E_NOTICE); 

    Функция сообщения об ошибках позволяет вам фильтровать, какие ошибки могут отображаться. Символ «~» означает «нет», поэтому параметр ~ E_NOTICE означает не показывать уведомления. Обратите внимание на символы «&» и «|» между возможными параметрами. Символ «&» означает «верно для всех», в то время как символ «|» представляет любой из них, если он истинен. Эти два символа имеют одинаковое значение в условиях PHP OR и AND.

    error_reporting(E_ALL); error_reporting(-1); ini_set('error_reporting', E_ALL); 

    Эти три строки кода делают одно и то же, они будут отображать все ошибки PHP. Error_reporting(E_ALL) наиболее широко используется разработчиками для отображения ошибок, потому что он более читабелен и понятен.

    Включить ошибки php в файл с помощью функции error_log ()

    У сайта на хостинге сообщения об ошибках не должны показываться конечным пользователям, но эта информация все равно должна быть записана в журнал (лог).

    Простой способ использовать файлы журналов — использовать функцию error_log, которая принимает четыре параметра. Единственный обязательный параметр — это первый параметр, который содержит подробную информацию об ошибке или о том, что нужно регистрировать. Тип, назначение и заголовок являются необязательными параметрами.

    error_log("There is something wrong!", 0); 

    Параметр type, если он не определен, будет по умолчанию равен 0, что означает, что эта информация журнала будет добавлена ​​к любому файлу журнала, определенному на веб-сервере.

    error_log("Email this error to someone!", 1, "someone@mydomain.com"); 

    Параметр 1 отправит журнал ошибок на почтовый ящик, указанный в третьем параметре. Чтобы эта функция работала, PHP ini должен иметь правильную конфигурацию SMTP, чтобы иметь возможность отправлять электронные письма. Эти SMTP-директивы ini включают хост, тип шифрования, имя пользователя, пароль и порт. Этот вид отчетов рекомендуется использовать для самых критичных ошибок.

    error_log("Write this error down to a file!", 3, "logs/my-errors.log"); 

    Для записи сообщений в отдельный файл необходимо использовать тип 3. Третий параметр будет служить местоположением файла журнала и должен быть доступен для записи веб-сервером. Расположение файла журнала может быть относительным путем к тому, где этот код вызывается, или абсолютным путем.

    Журнал ошибок PHP через конфигурацию веб-сервера

    Лучший способ регистрировать ошибки — это определить их в файле конфигурации веб-сервера.

    Однако в этом случае вам нужно попросить администратора сервера добавить следующие строки в конфигурацию.

    Пример для Apache:

    ErrorLog "/var/log/apache2/my-website-error.log" 

    В nginx директива называется error_log.

    error_log /var/log/nginx/my-website-error.log; 

    Теперь вы знаете, как в PHP включить отображение ошибок. Надеемся, что эта информация была вам полезна.

    Рекомендуемые статьи:

    • Как изменить версию PHP на сервере с Debian 10
    • PhpMyAdmin — как создать пользователя и базу данных
    • WordPress — как отключить управление сайтом через xmlrpc
    • Несколько причин медленной работы сайта на примере WordPress
    • WordPress — смена домена сайта при помощи wp-cli
    • Когда использовать index.php, а когда index.html
    • PHP. Как удалить элемент из массива
    • Дата и время в PHP
    • PHP. Различия между Fast-CGI, CGI, Mod-PHP, SuPHP, PHP-FPM
    • Простой пример кода на языке PHP
    • PHP. Проверка содержит ли строка определенное слово
    • Как предотвратить SQL инъекции в PHP
    • Как установить Linux, Apache, MySQL, PHP (LAMP) в Ubuntu 18.04
    • Несколько трюков и секретов PHP

    Обработка исключений и ошибок в PHP

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

    Пользоваться таким кодом очень сложно, поскольку приходится заключать каждую функцию/метод в блок try/catch, хотя было бы достаточно, если функция вернёт обычный false .

    Мне кажется, что основная причина такого использования исключений в том, что у php-программистов нет понимания зачем исключения вообще нужны, а также в том, что их часто путают с обработкой ошибок.

    Для новичков, которые не имеют опыта полноценного программирования (например на Pascal/Delphi) исключения — это вообще тёмный лес. Попробуем разобраться.

    Что такое «исключения»?

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

    Так вот под «исключением» понимается обработка исключительных ситуаций. Простой пример из «больших» языков.

    Считывается файл в какую-то переменную. Перед этим для этого выделяется блок памяти. В процессе чтения файла, возникает исключительная ситуация, например файл удалили или он заблокирован на чтение. Данная программа аварийно завершает свою работу, а значит участок памяти не был освобождён.

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

    На Паскале это может выглядеть так:

    try TreeView.LoadFromStream(stream); except showmessage('Ошибка загрузки потока. Что-то с системой. '); end;

    В данном примере блок try — это т.н. защищённый блок кода — если в нём возникнет исключение, то управление будет передано в блок except — это обработчик исключения.

    В другом примере используется блок finally .

    FIniFile := TRegIniFile.Create(s); try FIniFile.ReadString('', 'data',''); . finally FIniFile.Free; end;

    Здесь переменная FIniFile считывает некие данные, но если они ошибочные, то возникает исключение. Но здесь главная задача — это корректно освободить память и это происходит в блоке finally , который гарантированно сработает как при возникновении исключения, так и без него.

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

    Исключения в PHP

    В PHP исключения реализуются похожим образом.

    try < . защищённый участок кода . >catch (Exception $e)

    Или вариант с finally :

    try < . защищённый участок кода . >catch (Exception $e) < . код, если возникла исключительная ситуация . >finally

    При этом можно использовать как try/catch/finally , так и try/finally .

    Казалось бы всё просто, но как обычно в PHP есть нюансы.

    «Спотыкачка» для новичков

    Рассмотрим простой пример. Есть функция для деления двух чисел.

    function my1($a, $b) < try < $r = $a / $b; >catch (Exception $e) < $r = 'Нельзя делить на ноль'; >return $r; > echo my1(1, 0);

    Мы ожидаем, что выполнение этого выведет «Нельзя делить на ноль». Однако на самом деле мы получаем сообщение от PHP «Warning: Division by zero». То есть блок catch не сработал.

    Почему так происходит?

    Не все ошибки — исключения

    В PHP все ошибки имеют тип в виде предопределённых констант: E_ERROR, E_WARNING, E_NOTICE и т.д.

    Так вот ошибки E_WARNING не являются исключительной ситуацией, поскольку программа может продолжить своё выполнение дальше. Если после echo my1(1, 0); мы разместим ещё какой-то код, то PHP его выполнит.

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

    То есть когда мы пытаемся поделить число на ноль, то это всего лишь некорректная обработка входящих данных, которая не может привести к полному краху.

    Обработка данных

    PHP в первую очередь это процедурное программирование, где функции самостоятельно умеют обрабатывать входящие данные. Хороший пример это функции для текста, например strpos() , которая возвращает не только позицию вхождения, но и FALSE, если его нет.

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

    Наш пример можно было бы переписать так:

    function my2($a, $b) < if ($b == 0) return false; // 'Нельзя делить на ноль'; else return $a / $b; >if ($r = my2(1, 0) !== FALSE) echo $r; else echo 'Ошибка';

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

    Как не нужно делать

    Плохая практика — вместо обработки входящих данных, генерировать исключение. В PHP можно сгенерировать исключение вручную с помощью throw .

    function my3($a, $b) < if ($b === 0) throw new Exception('Нельзя делить на ноль'); else return $a / $b; >try < echo my3(1, 0); >catch (Exception $e) < echo $e->getMessage(); >

    Здесь, если $b равен нулю, генерируется исключение. Проблема здесь в том, что использовать такую функцию приходится только в блоке try/catch, что не только усложнят код, но и смешивает логику приложения с исключениями. Причём этот пример достаточно простой: если копнуть глубже, то исключения могут быть разных типов (классов) и их «ветвистая» обработка безумно усложняет код.

    Правильны подход

    Функция должна сама обрабатывать свои исключения.

    function my4($a, $b) < try < if ($b === 0) throw new Exception('Нельзя делить на ноль'); else return $a / $b; >catch (Exception $e) < return $e->getMessage(); > > echo my4(1, 0);

    Если $b равен нулю, генерируется исключение, которое тут же ловится в блоке catch . Это как бы совмещённый подход, когда функция и проверяет данные, и генерирует исключения. Поскольку можно отследить разные ситуации, то можно сгенерировать и разные исключения. Например если в функцию будет передано не число, а строка или другой нечисловой тип данных, то возвратить либо сообщение об ошибке, либо просто 0.

    Как отследить WARNING

    Важно понимать, что в PHP ошибки и исключения — разные вещи и работают они по разному. По большому счёту можно вообще обойтись без исключений, поскольку функции PHP сами по себе неплохо справляются с нештатными ситуациями.

    Однако в PHP есть механизм по «превращению» ошибок в исключения. Для этого следует переопределить стандартный обработчик ошибок с помощью функции set_error_handler() .

    function exception_error_handler($severity, $message, $file, $line) < if (!(error_reporting() & $severity)) < // Этот код ошибки не входит в error_reporting return; >throw new ErrorException($message, 0, $severity, $file, $line); > set_error_handler('exception_error_handler');

    После этого мы можем вызвать самый первый пример с my1()

    echo my1(1, 0);

    и получить как и ожидаем: «Нельзя делить на ноль».

    Выводы

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

    Если функция генерирует исключение, то лучше всего, если она сама же его и обработает.

    Плохо, если функция только генерирует исключение в надежде, что его «кто-то» «где-то» словит. И совсем плохо, если логика функции/приложения построена на исключениях. Такой подход негативно сказывается как на логике работы, так и на общем объёме кода. Разобраться в нём будет проблематично.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *