你如何在 PHP 7+ 中捕获可恢复的错误?

让我认为可以捕获可恢复的错误,但事实并非如此,如下所示:


<?php


$_SERVER['TEST'] = new stdClass;


try {

    phpinfo();

} catch (\Throwable $e) {}

如果您运行该代码,您将得到以下输出:


$_SERVER['argc'] => 1

$_SERVER['TEST'] =>

Recoverable fatal error: Object of class stdClass could not be converted to string in /Users/username/zzz.php on line 6

很明显,“发出”了一个错误,但没有抛出一个错误,除非我误解了什么?


慕工程0101907
浏览 272回答 1
1回答

回首忆惘然

并非所有错误都转换为ThrowablePHP 7 中的错误。实际上,文档说:大多数错误现在通过抛出错误异常来报告。(强调我的)。大多数 !== 全部。有些错误仍然无法捕捉。有趣的是,在 PHP 7.1 发布之前,您习惯于说“可捕获的致命错误”而不是“可恢复的致命错误”的错误消息。这被报告为错误,但开发人员实施的解决方案是将错误字符串从Catchable更改为Recoverable以消除误解。在您正在测试的特定情况下,似乎phpinfo()引发 arecoverable error而不是抛出 an Error,因此您无法以这种方式捕获它是有道理的。尽管如此,并不是所有的希望都破灭了。您可以做的是通过实现您自己的错误处理程序将所有错误转换为异常。ErrorException 文档中描述了一个示例:function exception_error_handler($severity, $message, $file, $line) {&nbsp; &nbsp; if (!(error_reporting() & $severity)) {&nbsp; &nbsp; &nbsp; &nbsp; // This error code is not included in error_reporting&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; throw new ErrorException($message, 0, $severity, $file, $line);}set_error_handler("exception_error_handler");这个例子的巧妙之处在于它考虑了您的错误报告设置,因此只有在您的设置下报告的错误才会作为异常实际抛出。否则,什么都不会发生。测试你的代码:<?phpfunction exception_error_handler($severity, $message, $file, $line) {&nbsp; &nbsp; if (!(error_reporting() & $severity)) {&nbsp; &nbsp; &nbsp; &nbsp; // This error code is not included in error_reporting&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; throw new ErrorException($message, 0, $severity, $file, $line);}set_error_handler("exception_error_handler");$_SERVER['TEST'] = new stdClass;try {&nbsp; &nbsp; phpinfo(INFO_VARIABLES);} catch (\Throwable $e) {echo 'CAUGHT!!!!!!';}打印以下输出:$_SERVER['TERM_SESSION_ID'] => w0t1p0:xxx-cxx-xxxxxxx-xxxxx$_SERVER['SSH_AUTH_SOCK'] => /private/tmp/com.apple.launchd.xxxxxxxx/Listeners$_SERVER['LC_TERMINAL_VERSION'] => 3.3.2....$_SERVER['argc'] => 1$_SERVER['TEST'] =>CAUGHT!!!!!!%
打开App,查看更多内容
随时随地看视频慕课网APP