正确的错误处理方式

时间:2013-02-22 09:52:46

标签: php

这更像是一个架构问题。我想知道人们对如何在完全面向对象的PHP环境中正确处理错误的看法。

例如,我有一个从数据库中检索所有用户数据的类。所以我会以这种方式使用它:

$userData = new UserDataConnection();
$userData->openDatabase();
$userData->retrieveData();
$userData->showData();
$userData->closeDatabase();

在每个步骤中,都可能发生错误。那么我会从每个步骤返回一个布尔值来说明函数是否已成功执行(因此错误检查在每个函数中),或者我是否围绕整个事件执行try-catch异常处理?还是有更好的方法?

当出现某种错误时,总是去某种错误页面也会更好吗?

2 个答案:

答案 0 :(得分:1)

<?php

$ERROR = false;
try {

    $userData = new UserDataConnection();
    $userData->openDatabase();
    $userData->retrieveData();
    $DETAILS = $userData->showData();
    $userData->closeDatabase();

} catch( Exception $e ) {

    $ERROR = $e->getMessage(); // exit;

}

if( $ERROR ) {
    $DETAILS = array();
}

?>

如果您使用PDO,则可以抛出PDOException。

答案 1 :(得分:1)

它通常归结为一个简单的问题:

这个功能可能“合法地”失败,或者是否有任何失败的迹象表明出现了什么问题?

如果函数需要某种输入,并且永远不应该使用不同类型的输入调用,则任何提供正确输入的失败都是InvalidArgumentException。对于不直接处理用户输入的函数尤其如此。这种类型提示效果更好。

如果函数在给定正确输入的情况下应始终产生某个结果,则函数产生该结果的任何失败都是RuntimeExceptionLogicException或其他类型的异常。

如果函数可能产生或不产生某种结果,false是合法的返回值。返回false时,处理用户输入并因此得到非常随意的输入值的函数通常很好。

一些例子:

    如果无法与数据库建立连接,则
  • getDatabaseConnection()完全正确抛出RuntimeException或类似内容。这是特殊情况,在这种情况下,无法继续工作。
  • transformFooIntoBar(Foo $foo)如果由于某种原因无法返回Bar实例,则抛出某种形式的异常是正确的。该功能具有明确的目的和类型检查输入值。如果它不能在如此明确的条件下完成工作,那么事情显然是错误的,必须加以解决。 Ergo,一个例外。
  • checkIfUserExists($id)可能会返回false,因为它的工作是竖起大拇指或竖起大拇指。在此作业说明的情况下,不存在的用户不是例外情况

捕获抛出异常的位置取决于您要处理它的位置。数据库连接错误应该可以在调用堆栈的最顶层捕获,因为如果数据库关闭,您可能无法执行任何操作。
另一方面,如果某个模块正在调用某个子模块,而另一半模块预计该子模块失败和/或有一个应急计划,以防它失败,模块可能会捕获子模块的异常并继续完成其工作。例如,getRSSUpdates()会调用HTTP::fetchContents($url)。如果URL返回404,则HTTP模块可能会抛出异常,因为在这些情况下它不能返回内容。尽管getRSSUpdates()函数已准备就绪,但将此情况称为“此时没有更新”。