1

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

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

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

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

发生某种错误时总是转到某种错误页面是否也更好?

4

2 回答 2

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。

于 2013-02-22T09:57:37.807 回答
1

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

这个功能可能会“合法地”失败,还是任何失败都是真正错误的迹象?

如果一个函数需要某种类型的输入并且永远不应该使用不同类型的输入来调用,那么任何未能提供正确输入的行为都是InvalidArgumentException. 对于不直接处理用户输入的函数尤其如此。这对类型提示更有效。

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

如果一个函数可能会或可能不会产生某种结果,false那么它就是一个合法的返回值。处理用户输入并因此获得非常任意输入值的函数通常可以返回false.

一些例子:

  • getDatabaseConnection()RuntimeException如果无法建立与数据库的连接,则抛出 a 或类似内容是完全正确的。这是一种特殊情况,在这种情况下无法继续工作。
  • transformFooIntoBar(Foo $foo)Bar无论出于何种原因,如果它无法返回实例,则抛出某种形式的异常是正确的。该函数具有明确的目的和类型检查的输入值。如果它不能在如此明确的条件下完成其工作,那么显然是有问题,必须加以修复。因此,一个例外。
  • checkIfUserExists($id)可能会返回false,因为它的工作是返回一个大拇指或大拇指向下。鉴于此职位描述,用户不存在并不是例外情况。

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

于 2013-02-22T11:57:51.473 回答