【问题标题】:PHP Error handling: die() Vs trigger_error() Vs throw ExceptionPHP 错误处理:die() Vs trigger_error() Vs throw Exception
【发布时间】:2011-10-27 03:26:18
【问题描述】:

关于 PHP 中的错误处理——据我所知有 3 种样式:

  1. die()exit()风格:

    $con = mysql_connect("localhost","root","password");
    
    if (!$con) {
     die('Could not connect: ' . mysql_error());
    }
    
  2. throw Exception风格:

     if (!function_exists('curl_init')) {
    
          throw new Exception('need the CURL PHP extension. 
                               Recomplie PHP with curl');
        }
    
  3. trigger_error()风格:

    if(!is_array($config) && isset($config)) {
            trigger_error('Error: config is not an array or is not set', E_USER_ERROR);
        }
    

现在,在 PHP 手册中使用了所有三种方法。

  • 我想知道我应该更喜欢哪种风格以及为什么?

  • 这 3 种产品是否可以相互替换,因此可以互换使用?

有点 OT:是我还是大家认为 PHP 错误处理选项只是 太多 到让 php 开发人员感到困惑的程度?

【问题讨论】:

  • 这些不是“样式”。它们是不同的语言特征。用于不同的目的。
  • @mario:不同的缩进目的是什么?请赐教:)
  • 你提出的问题很好。谢谢提问

标签: error-handling php


【解决方案1】:

第一个永远不应该在生产代码中使用,因为它传输与最终用户无关的信息(用户无法对“无法连接到数据库”做任何事情)。

如果您知道在某个关键代码点,您的应用程序可能会失败并且您希望您的代码跨多个调用级别恢复,那么您会抛出异常。

trigger_error() 让您可以进行细粒度的错误报告(通过使用不同级别的错误消息),并且您可以向最终用户隐藏这些错误(使用 set_error_handler()),但在测试期间仍会向您显示这些错误。

此外,trigger_error() 可以生成在开发过程中重要的非致命消息,可以使用自定义错误处理程序在生产代码中抑制这些消息。您也可能产生致命错误 (E_USER_ERROR),但这些错误无法恢复。如果您触发其中之一,则程序执行停止。这就是为什么对于致命错误,应该使用异常。这样,您就可以更好地控制程序的流程:

// Example (pseudo-code for db queries):

$db->query('START TRANSACTION');

try {
    while ($row = gather_data()) {
       $db->query('INSERT INTO `table` (`foo`,`bar`) VALUES(?,?)', ...);
    }
    $db->query('COMMIT');
} catch(Exception $e) {
    $db->query('ROLLBACK');
}

在这里,如果 gather_data() 只是简单粗暴(使用 E_USER_ERRORdie()),则有机会,以前的 INSERT 语句会进入您的数据库,即使不需要并且您无法控制关于接下来会发生什么。

【讨论】:

  • 所以在trigger_error() 和抛出异常中:我应该使用哪个以及何时?
  • @Gaurish 查看添加的示例。
  • 阅读您的示例后,我想现在我更好地理解了抛出异常背后的目的。谢谢:)
  • @Pacerier 实际上,这取决于服务器的配置。系统可能默认配置为autocommit,因此显式ROLLBACK。这个伪代码示例涵盖了两种情况:未配置为自动提交的服务器(需要 COMMIT 语句)和配置为自动提交的服务器。
  • @LinusKleen,一旦我们运行query('START TRANSACTION');这一行,自动提交是不是关闭了?
【解决方案2】:

我通常在开发代码中使用第一种方式进行简单的调试。不建议用于生产。最好的方法是抛出一个异常,你可以在程序的其他部分捕获它并对其进行一些错误处理。

这三种样式不是相互替代的。第一个根本不是错误,只是一种停止脚本并输出一些调试信息供您手动解析的方法。第二个本身不是错误,但如果您没有捕获它,它将转换为错误。最后一个是在 PHP 引擎中触发一个真正的错误,该错误将根据您的 PHP 环境的配置进行处理(在某些情况下向用户显示,在其他情况下只是登录到文件或根本不保存)。

【讨论】:

  • 抛出异常但未被捕获时会发生什么?我猜这会导致致命错误。而trigger_error() 也会发生同样的事情。那么有什么区别呢?
  • 不同之处在于你可以捕获异常并以任何你想要的方式处理它。
  • @EmilVikström 但是错误也可以被自定义错误处理程序捕获。此外,由于 PHP7 错误和异常都基于 throwable 接口。从 PHP8 开始,还有一个名为 Error 的类。当我查看此类的类定义并将其与 Exception 类进行比较时,唯一的区别是类名。所以我会假设 Error 类是 Exception 类的后代。但我不确定。
猜你喜欢
  • 2012-06-04
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
相关资源
最近更新 更多