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

Posted

技术标签:

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

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

    die()exit()风格:

    $con = mysql_connect("localhost","root","password");
    
    if (!$con) 
     die('Could not connect: ' . mysql_error());
    
    

    throw Exception风格:

     if (!function_exists('curl_init')) 
    
          throw new Exception('need the CURL PHP extension. 
                               Recomplie PHP with curl');
        
    

    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:不同的缩进目的是什么?请赐教:) 你提出的问题很好。谢谢提问 【参考方案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 类的后代。但我不确定。

以上是关于PHP 错误处理:die() Vs trigger_error() Vs throw Exception的主要内容,如果未能解决你的问题,请参考以下文章

PHP 错误处理

PHP:php错误/警告/通知的双重输出

在 PHP 中,为啥“or die()”有效,而“or return”无效?

php错误处理

PHP基础PHP教程(错误处理异常处理)

PHP-异常-1