当前位置: 首页 > 知识库问答 >
问题:

捕获错误异常包装一个致命的PHP错误

蓝昊然
2023-03-14

在我自制的PHP MVC框架中,我编写了一个小错误处理程序,它将PHP错误包装在异常中,然后抛出它。

class ErrorController extends ControllerAbstract {

    ...

    public static function createErrorException($number, $message = NULL, $file = NULL, $line = NULL, array $context = array()) {
        throw new ErrorException($message, $number, 0, $file, $line);
    }
}

然后使用set\u error\u handler()注册。除了致命的错误(没有双关语)之外,这一切都很好。我的自定义错误处理程序仍被调用,但我无法捕获抛出的ErrorException

这种错误的一个例子是试图包含一个不存在的文件:

    try {
        require 'Controller/NonExistentController.php';
    } catch (ErrorException $exc) {
        echo $exc->getTraceAsString(); // code never reaches this block
    }

调用我的自定义错误处理程序并抛出异常,但代码永远不会到达“catch”块。相反,PHP会生成HTML(糟糕!):


警告:未捕获异常“ErrorException”,消息为“require(Controller/NonExistentController.php):无法打开流:。。。

然后:

致命错误:程序::main():失败的打开需要控制器/不存在的Controller.php(include_path='.:') ...

我不想尝试从致命错误中恢复,但我确实希望我的代码优雅地退出。在这种情况下,这意味着发送一个指示内部错误的XML或JSON响应,因为这是一个REST应用程序,这是我的客户所期望的。超文本标记语言响应很可能也会破坏客户端应用程序。

我应该换一种方式吗?

共有2个答案

祁晟
2023-03-14

我很抱歉得到这样一个否定的答案,但你(很可能)不能。

PHP被设计成尽可能长时间的突突,因为一些奇怪的原因,你有打字错误吗?默默地将变量初始化为null,你把[]放在某物之后,如果运算符没有意义,则计算为null!

这对于错误处理来说是非常混乱的,有4个系统不在一起工作。PHP通过“monkey patching”进行一些错误处理,这会导致一个问题,如果您试图通过抛出来处理错误处理程序中的某些内容,那么在处理程序退出之前,它不会“unpatchid”。

有了关机处理程序,从那里扔会导致巨大的问题!它以前咬过我的屁股,我不想谈论它: P

它也是一个实现,定义为在关闭时是否关闭文件“资源”,它是为了帮助插件整理网络服务器而创建的。(因此你可以有一个它们的列表)

闻人栋
2023-03-14

看留档关于要求在php.net:

要求与包含相同,除非失败时它也会产生致命的E_COMPILE_ERROR级错误。换句话说,它将停止脚本,而包括只发出允许脚本继续的警告(E_WARNING)。

在您的情况下,您可以借助注册_shutdown_函数处理致命错误,这需要PHP 5.2:

function customFatalHandler() {
  $error = error_get_last();

  if( $error === NULL) {
      return;
  }

  $type   = $error["type"];
  $file = $error["file"];
  $line = $error["line"];
  $message  = $error["message"];

  echo "Error `$type` in file `$file` on line $line with message `$message`"; 
}

register_shutdown_function("customFatalHandler");

这对你也有帮助

  1. 错误_get_last()和自定义错误处理程序
  2. 为什么PHP没有捕捉到“未找到类”错误
 类似资料:
  • 我在进行贝宝支付时出现了经验错误。 致命错误:未捕获异常“PayPal\exception\PayPalConnectionException”,消息为“访问https://api.sandbox.paypal.com/v1/payments/payment时获得Http响应代码400”。在C:\xampp\htdocs\paypal\workload\third_party\vendor\pay

  • 我试图用wsdl,肥皂和PHP做一个测试,我得到了错误: 致命错误:未捕获的SoapFault异常[wsdl]SOAP-ERROR 我现在有2个文件,一个是给定的wsdl,client.php只是为了测试: 我犯了一个错误: 致命错误:未捕获的SoapFault异常:[WSDL]SOAP-error:分析WSDL:无法从“hp://localhost/test/service/wbs”加载。wsd

  • 我现在必须学习通过fire base编写移动应用程序web服务。我点击了这个链接:https://firebase-php.readthedocs.io/en/stable/ 在我的核心网站中,我创建web服务文件夹,然后创建我的fire。php文件。这个文件代码在这里, 我得打电话给我的支持档案:https://github.com/kreait/firebase-php/ 但我还是得到了一个:

  • 我正在尝试运行MySQL PDO查询。我不知道为什么我会得到一个致命的错误。我查过其他帖子,但他们的答案似乎并不能解决我的。 脚本连接到数据库很好。用户名和密码是正确的,我已经在下面的脚本中删除了它们。 我的输出:

  • 我得到这个错误。我创建了一个按钮来更新表。当我点击按钮时,我得到一个错误。如何修复它? 致命错误:Uncaught ArgumentCounter错误:函数personel::update_form(),0的参数太少,在C:\xampp\htdocs\warehouse\panel\system\core\CodeIgniter中传递。php在第360行,C:\xampp\htdocs\wareh

  • 我如何解决这个问题。 这是我的网站 这是完全的错误。 致命错误:未捕获的异常“exception”,消息为“DateTime::\u构造():无法分析位置0(0)处的时间字符串(03-22-2016):在/home/budweiser/public\u html/verify中出现意外字符”。php:13堆栈跟踪:#0/home/budweiser/public_html/verify。php(1