Intereting Posts
PHP формат даты даты dd / mm / yyyy => yyyy-mm-dd Получить цену товара на рынке сообщества Steam с помощью PHP и Regex Загрузка файла через https с помощью файла cordova filetransfer Узлы сортировки и обновления PHP как вы обнаруживаете, пришел ли ваш посетитель сайта из результатов поиска Google? Доступ к относительным файлам CSS / JS с правилом перезаписи htaccess MYSQL ограничивает доступ пользователей к information_schema Использование PDO для эха отображает все строки из таблицы yii несколько внутренних объединений Есть ли какие-либо альтернативы для работы в Cron? Получение timestamp unix в миллисекундах в PHP5 и ActionScript3 MySQL INSERT … ON DUPLICATE UPDATE – добавляет один к автоинкременту Как я могу использовать процессор и память? Невозможно отправить уведомление группе с помощью кнопки уведомления, даже если это возможно через regId Как я могу убить процессы, соответствующие grep старше 30 минут?

PHP: пользовательский обработчик ошибок – обработка синтаксических ошибок и фатальных ошибок

Как я могу обрабатывать синтаксические ошибки и фатальные ошибки с помощью специального обработчика ошибок?

Простой ответ: вы не можете. См. Руководство :

Следующие типы ошибок не могут быть обработаны с помощью определенной пользователем функции: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING и большая часть E_STRICT, поднятых в файле, где вызывается set_error_handler ().

Для каждой другой ошибки вы можете использовать set_error_handler()

РЕДАКТИРОВАТЬ:

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

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

Фактически вы можете обрабатывать синтаксические разборки и фатальные ошибки. Верно, что функция обработчика ошибок, которую вы определили с помощью set_error_handler (), не будет вызываться. Способ сделать это – определить функцию выключения с помощью register_shutdown_function (). Вот что я работаю на своем сайте:

Файл prepend.php (этот файл будет автоматически добавлен ко всем скриптам php). Ниже приведены советы по добавлению файлов на PHP.

 set_error_handler("errorHandler"); register_shutdown_function("shutdownHandler"); function errorHandler($error_level, $error_message, $error_file, $error_line, $error_context) { $error = "lvl: " . $error_level . " | msg:" . $error_message . " | file:" . $error_file . " | ln:" . $error_line; switch ($error_level) { case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_PARSE: mylog($error, "fatal"); break; case E_USER_ERROR: case E_RECOVERABLE_ERROR: mylog($error, "error"); break; case E_WARNING: case E_CORE_WARNING: case E_COMPILE_WARNING: case E_USER_WARNING: mylog($error, "warn"); break; case E_NOTICE: case E_USER_NOTICE: mylog($error, "info"); break; case E_STRICT: mylog($error, "debug"); break; default: mylog($error, "warn"); } } function shutdownHandler() //will be called when php script ends. { $lasterror = error_get_last(); switch ($lasterror['type']) { case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: case E_RECOVERABLE_ERROR: case E_CORE_WARNING: case E_COMPILE_WARNING: case E_PARSE: $error = "[SHUTDOWN] lvl:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line']; mylog($error, "fatal"); } } function mylog($error, $errlvl) { ...do whatever you want... } 

PHP вызовет функцию errorHandler (), если он поймает ошибку в любом из скриптов. Если ошибка заставляет скрипт немедленно отключиться, ошибка обрабатывается функцией shutdownHandler ().

Это работает на сайте, который я разрабатываю. Я еще не тестировал его на производстве. Но в настоящее время он ловит все ошибки, которые я нахожу при разработке.

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

TODOх:

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

2 – Реализация обработки ошибок для всех вызовов MySQL.

3 – Внедрить обработку ошибок для моего кода javascript.

ВАЖНЫЕ ЗАМЕТКИ:

1 – Я использую следующую строку в своем php.ini, чтобы автоматически добавить вышеприведенный скрипт ко всем скриптам php:

 auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php" 

это работает хорошо.

2 – Я регистрирую и разрешаю все ошибки, включая ошибки E_STRICT. Я верю в разработку чистого кода. Во время разработки мой файл php.ini имеет следующие строки:

 track_errors = 1 display_errors = 1 error_reporting = 2147483647 html_errors = 0 

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

Я надеюсь, что это помогает кому-то.

Вы можете отслеживать эти ошибки, используя следующий код:

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

 function shutdown() { $isError = false; if ($error = error_get_last()){ switch($error['type']){ case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: $isError = true; break; } } if ($isError){ var_dump ($error);//do whatever you need with it } } register_shutdown_function('shutdown'); 

Из комментариев PHP.net на странице http://www.php.net/manual/en/function.set-error-handler.php

Я понял, что несколько человек здесь упомянули, что вы не можете захватить ошибки разбора (тип 4, E_PARSE). Это неправда. Вот как я это делаю. Я надеюсь, что это помогает кому-то.

1) Создайте файл auto_prepend.php в корневом каталоге и добавьте следующее:

 <?php register_shutdown_function('error_alert'); function error_alert() { if(is_null($e = error_get_last()) === false) { mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true)); } } ?> 

2) Затем добавьте этот «php_value auto_prepend_file /www/auto_prepend.php» в ваш .htaccess файл в корневом каталоге.

  • убедитесь, что вы изменили адрес электронной почты и путь к файлу.

Сценарий с ошибкой синтаксического разбора всегда прерывается и его нельзя обрабатывать. Поэтому, если скрипт вызывается напрямую или include / require, вы ничего не можете сделать. Но если он вызывается AJAX, flash или каким-либо другим способом, есть обходное решение, как обнаружить ошибки синтаксического анализа.

Мне понадобилось это для обработки скрипта swfupload . Swfupload – это флеш-память, которая обрабатывает загрузку файлов и загружается каждый раз, она вызывает скрипт обработки PHP для обработки filedata – но нет выхода для браузера, поэтому скрипт обработки PHP нуждается в этих настройках для целей отладки:

  • предупреждения и уведомления ob_start (); в начале и сохранить содержимое в сеансе ob_get_contents (); в конце скрипта обработки: это может отображаться в браузере другим скриптом
  • фатальные ошибки register_shutdown_function (), чтобы установить сеанс с таким же трюком, как указано выше
  • проанализируйте ошибки, если ob_get_contents () находится в конце скрипта обработки, и ранее произошла ошибка синтаксического анализа, сеанс не заполнен (это значение равно null). Сценарий отладки может обрабатывать его следующим образом: if(!isset($_SESSION["swfupload"])) echo "parse error";

Примечание 1 null is not set в isset()

По моему опыту вы можете поймать все типы ошибок, скрыть сообщение об ошибке по умолчанию и отобразить собственное сообщение об ошибке (если хотите). Ниже перечислены то, что вам нужно.

1) Сценарий начального / верхнего уровня, назовем его index.php где вы храните свои пользовательские функции обработчика ошибок. Пользовательские обработчики функций ошибок должны оставаться наверху, чтобы они ломали ошибки под ними, «ниже», я имею в виду вложенные файлы.

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

3) Директивы Php (также должны быть найдены в index.php ) set_error_handler("myNonFatalErrorHandler"); #, чтобы поймать register_shutdown_function('myShutdown'); ошибки register_shutdown_function('myShutdown'); # для обнаружения фатальных ошибок ini_set('display_errors', false); #, чтобы скрыть ошибки, отображаемые пользователю по php ini_set('log_errors',FALSE); #assuming мы регистрируем ошибки сами себя ini_set('error_reporting', E_ALL); # Нам нравится сообщать обо всех ошибках

в то время как в производстве (если я не ошибаюсь), мы можем оставить ini_set('error_reporting', E_ALL); как и для того, чтобы иметь возможность регистрировать ошибку, в то же время ini_set('display_errors', false); убедитесь, что пользователю не отображаются ошибки.

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

 function myNonFatalErrorHandler($v, $m, $f, $l, $c){ $some_logging_var_arr1[]="format $v, $m, $f, ".$err_lvl[$l].", $c the way you like"; //You can display the content of $some_logging_var_arr1 at the end of execution too. } function myShutdown() { if( ($e=error_get_last())!==null ){ $some_logging_var_arr2= "Format the way you like:". $err_level[$e['type']].$e['message'].$e['file'].$e['line']; } //display $some_logging_var_arr2 now or later, eg from a custom session close function } 

как для $ err_lvl это может быть:

 $err_lvl = array(E_ERROR=>'E_ERROR', E_CORE_ERROR=>'E_CORE_ERROR', E_COMPILE_ERROR=>'E_COMPILE_ERROR', E_USER_ERROR=>'E_USER_ERROR', E_PARSE=>'E_PARSE', E_RECOVERABLE_ERROR=>'E_RECOVERABLE_ERROR', E_WARNING=>'E_WARNING', E_CORE_WARNING=>'E_CORE_WARNING', E_COMPILE_WARNING=>'E_COMPILE_WARNING', E_USER_WARNING=>'E_USER_WARNING', E_NOTICE=>'E_NOTICE', E_USER_NOTICE=>'E_USER_NOTICE',E_STRICT=>'E_STRICT');