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


PHP Error handling: die() Vs trigger_error() Vs throw Exception

关于PHP中的错误处理——据我所知有三种风格:

  1. die()exit()样式:

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

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

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

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

  • 我想知道的是我应该喜欢哪种风格&为什么?

  • 这3个drop in是互相替换的吗?因此可以互换使用吗?

稍微有点偏离:是只有我还是每个人都认为PHP错误处理选项太多了,以至于让PHP开发人员感到困惑?

第一个不应该在产品代码中使用,因为它传输的信息与最终用户无关(用户不能对"Cannot connect to database"做任何事情)。

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

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

另外,trigger_error()可以在开发过程中产生重要的非致命消息,这些消息可以使用自定义错误处理程序在生产代码中抑制。您也可以产生致命错误(E_USER_ERROR),但这些错误是不可恢复的。如果触发其中一个,程序执行将在该点停止。这就是为什么对于致命错误,应该使用exception的原因。这样,您将对程序流有更多的控制:

// 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语句将进入您的数据库,即使不需要,您也无法控制接下来发生的事情。

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

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