如何使用自定义错误处理程序处理解析和致命错误?
发布于 2009-12-14 18:59:58
简单的答案是:你不能。请看manual
无法使用用户定义的函数处理以下错误类型: E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING以及在调用set_error_handler()的文件中引发的大多数E_STRICT。
对于其他所有错误,都可以使用set_error_handler()
编辑:
由于似乎有一些关于这个主题的讨论,关于使用register_shutdown_function
,我们应该看看处理的定义:对我来说,处理错误意味着捕获错误并以一种对用户和底层数据(数据库、文件、web服务等)“友好”的方式做出反应。
使用register_shutdown_function
,您不能从调用代码的地方处理错误,这意味着代码仍然会在错误发生的地方停止工作。但是,您可以向用户显示错误消息而不是白页,但是,例如,您不能回滚代码在失败之前所做的任何操作。
发布于 2011-09-06 08:29:44
实际上,您可以处理解析和致命错误。使用set_error_handler()定义的错误处理函数将不会被调用,这是事实。方法是使用register_shutdown_function()定义一个关闭函数。以下是我在我的网站上的工作:
File 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()处理该错误。
这是我正在开发的网站上的工作。我还没有在生产中测试它。但它目前正在捕获我在开发它时发现的所有错误。
我认为存在两次捕获相同错误的风险,每个函数捕获一次。如果函数errorHandler()也捕获到我在函数shutdownHandler()中处理的错误,则可能会发生这种情况。
待办事项:
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错误消息的风险。
我希望这对某些人有帮助。
发布于 2009-12-14 19:08:25
您可以使用如下代码跟踪这些错误:
(只有当解析错误通过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');
https://stackoverflow.com/questions/1900208
复制相似问题