我正在尝试更新旧的应用程序以利用较新的 PHP 8.2+ 功能。许多内部 PHP 错误现在会自动作为
ErrorException
对象抛出。
您可以设置自定义函数来处理任何被抛出但未被捕获的
ErrorException
对象。
问题是,有时,PHP 似乎会抛出 both 一个
ErrorException
对象,同时还使用旧的错误处理程序。这会导致相同的错误被处理两次。
请考虑以下简化代码:
// Setup Error Handling
ErrorHandler::Init();
// Try to include a file that doesn't exist:
require '/path/to/nothing.php';
// The simple error class:
abstract class ErrorHandler {
static public function Init(){
set_exception_handler('ErrorHandler::FinalException');
set_error_handler('ErrorHandler::BasicErrorHandler');
}
static public function FinalException($e){
echo '<br>FinalException() TRIGGERED!<br>';
}
static public function BasicErrorHandler($errorNo){
echo '<br>ErrorHandler() TRIGGERED!<br>';
}
}
当出现丢失文件错误时,输出为:
ErrorHandler() TRIGGERED!
FinalException() TRIGGERED!
也就是说,异常处理程序和错误处理程序都针对同一错误运行。
如果可能的话,我宁愿只使用异常。但如果我不使用
set_error_handler()
,除了异常之外,我仍然会收到标准错误消息。它只是没有传递给处理程序。
是否可以设置一个标志来关闭所有旧式错误处理并仅使用异常,这样我除了
set_error_handler()
之外不需要设置set_exception_handler()
?
如果没有,我如何在我的自定义错误处理程序(总是先运行)中检测到相同的错误是否也会被 PHP 作为
ErrorException
抛出,这样它就不会被处理两次?
我在这个ThrowableHandler.php上花费了很多年。我什至仅仅因为它就找到了一份工作参见截图。
搞乱运行时方面通常是不好的做法。善待邻居(不要试图将异常变成错误,反之亦然)。因此,为了养成更好的习惯,我们利用 Throwable 类,PHP 中抛出的所有东西都必须扩展该类。因此,下面的示例将捕获任何错误或异常。 免责声明
some ERRORS like E_DEPRECATED CANNOT BE CAUGHT in a try-catch block
,有些RECOVERABLE_WARNINGS
实际上是致命的,比如达到最大文件描述符。因此,set_exception_handler
和 set_error_handler
可能会在极其恶劣的情况下以及您意想不到的情况下被解雇。一旦调用,错误就很容易复合。让你的错误捕捉器被自己调用将会发生,并且你需要具有超级容错能力,以免它递归到被遗忘。如果你的粉丝开始旋转并且请求没有返回,那么你可能已经遇到了这种情况。
try {
} catch (Throwable $e) {
ThrowableHandler::generateLog($e);
}
如果您引用我链接的 GitHub 存储库,您将看到
set_exception_handler
和 set_error_handler,
,它们基本上只是调用 generateLog.