我使用下面的函数来设置我自己的错误处理程序和异常处理程序。
set_error_handler
set_exception_handler
错误处理程序将错误转换为异常。(抛出一个新的异常)
但是这些异常不会被我自己的异常处理程序捕获。
错误处理程序示例:
function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) {
throw new Exception("this was an error");
}
异常处理程序示例:
function exceptionHandler($e){
// don't get here when exception is thrown in error handler
Logger::logException($e);
}
(I think this cannot work anyway)
应该这样做吗?
或者有人能解释一下为什么它不能工作吗?
编辑:我做了一些测试,应该可以。
ErrorHandler中抛出的异常被ExceptionHandler捕获在ExceptionHandler中触发的错误被ErrorHandler处理
仅供参考。
My Problem have to other other
编辑:
我仍然没有发现为什么errorHandler中抛出的异常没有被我的exceptionHandler捕获。
例如,当我在代码的某个地方有这个
trigger_error("this is an error"); // gets handled by the errorHandler
throw new Exception("this is an exception"); // gets handler by the exceptionHandler
错误会被errorHandler处理,但是errorHandler中抛出的异常不会被exceptionHandler处理。
但是,如果在触发错误的地方抛出异常,则异常处理程序将处理该异常。
(希望你能理解我的意思)
我一点头绪都没有。有什么想法吗,我要找的问题?
OP观察到错误处理程序抛出的一些异常不能被捕获,这实际上是正确的:
function errorHandler($errno, $errstr, $errfile, $errline) {
throw new Exception($errstr);
}
function exceptionHandler($e) {
echo "exceptionHandler: '", $e->getMessage(), "''n";
}
set_error_handler("errorHandler");
set_exception_handler("exceptionHandler");
// this works as expected
$a = $foo;
// this does not
$a = $foo();
在最后一行中,实际上连续触发了两个错误:
- 未定义变量:foo" (E_NOTICE)
- "函数名必须是字符串" (E_ERROR)
可以期望errorHandler()
捕获E_NOTICE并抛出异常,然后由exceptionHandler()
处理。由于exceptionHandler()
永远不会返回,执行应该停止在那里。
但事实并非如此:errorHandler()
确实被调用并抛出异常,但在exceptionHandler()
可以做出反应之前,PHP决定退出,因为致命的E_ERROR。
这很不幸,而且据我所知没有通用的解决方案。您可以做的一件事是不从错误处理程序中调用throw new Exception(...)
,而是直接调用exceptionHandler(new Exception(...))
。这可以像预期的那样工作,但缺点是您不能再try .. catch
PHP错误了。
更新2014-04-30:
这显然已经在PHP 5.5中修复了(或者可能是5.4,我现在无法测试)。$foo
和$foo()
现在的行为方式相同,它们都产生输出exceptionHandler: 'Undefined variable: foo'
。
我看到两个可能的原因,为什么你的异常处理程序没有被调用:
- 没有异常;或
- 您正在捕获异常。
如果您为set_error_handler
提供第二个参数$error_types
,则有可能不会为PHP错误引发异常,这改变了应该调用自定义处理程序的错误级别。
更可能的原因是您已经在try...catch
块中捕获了异常。自定义异常处理程序仅在未捕获的异常:
function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) {
throw new Exception("this was an error");
}
function exceptionHandler($e) {
echo 'exceptionHandler';
}
set_error_handler('errorHandler');
set_exception_handler('exceptionHandler');
try {
file_get_contents('foo');
} catch (Exception $e) {
echo $e->getMessage(); // exceptionHandler() not called
}
file_get_contents('foo'); // exceptionHandler() is called
我还建议您看一下内置的ErrorException类:
function errorHandler($errno, $errstr, $errfile, $errline) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}