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_ERROR
或 die()
),则有机会,以前的 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的主要内容,如果未能解决你的问题,请参考以下文章