Если вы недавно обновили свою версию php, вы можете забыть перезагрузить службу веб-сервера.
Простой ответ: вы не можете. См. Руководство :
Следующие типы ошибок не могут обрабатываться с помощью определенной пользователем функции: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING и большая часть E_STRICT поднятый в файле, где вызывается set_error_handler ().
blockquote>Для каждой другой ошибки вы можете использовать
set_error_handler()
EDIT:
Поскольку кажется, что есть несколько дискуссий по этой теме, в отношении использования
register_shutdown_function
, мы должны взглянуть на определение обработки: для меня обработка ошибки означает ловить ошибку и реагировать таким образом, что это «приятно» «для пользователя и базовые данные (базы данных, файлы, веб-службы и т. д.).Используя
register_shutdown_function
, вы не можете обрабатывать ошибку из кода, в котором она была так что код все равно перестанет работать в точке, где происходит ошибка. Однако вы можете представить пользователю сообщение об ошибке вместо белой страницы, но вы не можете, например, отбросить все, что ваш код сделал до сбоя.
Из комментариев PHP.net на странице http://www.php.net/manual/en/function.set-error-handler.php
Я понял, что несколько человек здесь упомянули, что вы не можете захватить ошибки разбора (тип 4, E_PARSE). Это неправда. Вот как я это делаю. Я надеюсь, что это помогает кому-то.
1) Создайте файл auto_prepend.php в корневом каталоге веб-сайта и добавьте следующее:
blockquote><?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 файл в корневом каталоге.
blockquote>
- убедитесь, что вы изменили адрес электронной почты и путь к файлу.
Скрипт с ошибкой синтаксического разбора всегда прерывается и его нельзя обрабатывать. Поэтому, если скрипт вызывается напрямую или include / require, вы ничего не можете сделать. Но если он вызывается AJAX, flash или каким-либо другим способом, есть способ обхода ошибок синтаксического анализа.
Мне нужно было это, чтобы обрабатывать скрипт swfupload . Swfupload - это флеш-память, которая обрабатывает загрузку файлов и загружается каждый раз, она вызывает скрипт обработки PHP для обработки filedata, но нет выхода для браузера, поэтому скрипт обработки PHP нуждается в этих настройках для целей отладки:
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');
# для того, чтобы улавливать фатальные ошибки ini_set('display_errors', false);
#, чтобы скрыть ошибки, отображаемые пользователю по php ini_set('log_errors',FALSE);
#, чтобы мы регистрировали ошибки сами себя ini_set('error_reporting', E_ALL);
# Нам нравится сообщать обо всех ошибках
во время производства (если я не ошибаюсь), мы можем оставить ini_set('error_reporting', E_ALL);
как есть, чтобы иметь возможность регистрировать ошибку, в то же время ini_set('display_errors', false);
будет убедиться, что нет ошибки отображаются пользователю.
Что касается фактического содержимого двух функций, о которых я говорю, myNonFatalErrorHandler
и 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, e.g. 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');
На самом деле вы можете обрабатывать синтаксические и фатальные ошибки. Верно, что функция обработчика ошибок, которую вы определили с помощью 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's:
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.
Надеюсь, это поможет кому-то.
E_DEPRECATED
и E_USER_DEPRECATED
также должны быть включены в пользовательскую функцию обработчика ошибок.
– Wh1T3h4Ck5
19 September 2017 в 03:38
Вы можете отслеживать эти ошибки с помощью кода следующим образом:
(Ошибки анализа могут быть обнаружены только в том случае, если они встречаются в других файлах сценария через 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');
index.php
& amp; затем включите его в свой скрипт, используя include(index.php)
. Но он все еще не может поймать ошибки синтаксического анализа (синтаксическая ошибка). Я не думаю, что это возможно, не встраивая его в php.ini.
– Khurshid Alam
20 August 2014 в 19:31