PHP错误处理:die()Vs trigger_error()Vs throw Exception


118

关于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开发人员感到困惑?


4
这些不是“样式”。它们是不同的语言功能。用于不同的目的。
马里奥

11
@mario:缩进的目的有哪些?请赐教:)
CuriousMind 2011年

您很好地提出了问题。感谢您的
提问

Answers:


85

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

如果您知道在某个关键代码点上您的应用程序可能会失败,并且您希望代码在多个调用级别之间进行恢复,则会引发Exception 。

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,那么即使不希望使用以前的语句也可以将它放入数据库,并且您无法控制接下来要发生的事情。


2
因此,出于trigger_error()例外:我应该在什么时候使用&?
CuriousMind 2011年

@Gaurish参见添加的示例。
莱纳斯·克莱恩

2
阅读您的示例后,我认为现在我更好地理解了引发异常的目的。谢谢:)
CuriousMind 2011年

1
@Pacerier实际上,这取决于服务器的配置。系统可能被配置为默认自动提交,因此显示为ROLLBACK。此伪代码示例涵盖了两种情况:未配置为自动提交(COMMIT要求使用该语句)的服务器和那些配置为自动提交的服务器。
Linus Kleen

1
@LinusKleen,运行该行后,是否不会关闭自动提交功能query('START TRANSACTION');
Pacerier

10

我通常使用第一种方法在开发代码中进行简单调试。不建议将其用于生产。最好的方法是引发异常,您可以捕获该异常,然后在程序的其他部分进行一些错误处理。

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


1
当引发异常但未捕获异常时会发生什么?我猜这会导致致命错误。并trigger_error()发生同样的事情。那有什么区别?
CuriousMind 2011年

4
区别在于您可以捕获异常并以所需的任何方式对其进行处理。
埃米尔Vikström
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.