【问题标题】:Is returning error objects in PHP bad habit?在 PHP 中返回错误对象是坏习惯吗?
【发布时间】:2012-01-28 10:25:14
【问题描述】:

我是 php 新手,我对从方法到调用者似乎没有错误对象通信这一事实感到有些困惑。

这两种是我学习使用的方式:

    1234563
  1. 另一方面,如果方法需要向调用者发回一些错误信息,则应引发异常。

来自 COCOA,我学会了在特殊情况下使用异常(由于程序员错误导致的不可恢复的错误)。在任何其他情况下,只需将错误对象传递给调用者即可。

  • PHP 中的哲学有什么不同吗?
  • 异常是向调用者发回错误数据的标准机制吗?
  • 我是否应该避免编写自己的错误对象并将其作为输出参数传递给方法以与 PHP 模式保持一致?

【问题讨论】:

  • 我要转过头来问“什么时候最好返回错误对象而不是引发异常?”。

标签: php error-handling


【解决方案1】:

PHP 有两种主要机制来指示和处理程序流程中的错误:

选择哪个取决于您的个人喜好。异常是对象,所以如果你想做 OOP 或者来自另一种也使用异常的语言,你可能想要使用它们。基于非异常的错误处理适用于 PHP 可以发出的所有通知、警告和错误,以及您拥有这些的变体。如果您想将这些转换为异常,请查看ErrorException

但是,正如您已经提到的:例外情况适用于不可恢复的情况。它们用于管理常规控制流。因此,异常不是将错误消息发送回调用者的某种标准机制,例如你不应该这样做:

class FooValidator
{
    public function isValid($valueToValidate)
    {
        if ($this->satisfiesRules($valueToValidate) {
            return true;
        }
        throw new ValidationException('Foo didnt satisfy rule Bar');
    }
}

他们尝试/在调用者中捕获它。验证失败是一种可恢复的情况。

一种选择是引入Notification Object

class FooValidator
{
    public function isValid($valueToValidate, Notification $notification)
    {
        if ($this->satisfiesRules($valueToValidate) {
            return true;
        }
        $notification->addMessage('Foo didnt satisfy rule Bar');
        return false;
    }
}

在上面的示例中,Validator 仅返回一个布尔值,但可以在传递的 Notification 对象中收集有关验证失败原因的其他信息。这比从调用中返回错误对象要干净得多,因为我们不必检查返回类型。如果验证返回 false,我们知道我们可以检查 Notification 对象。由于对象是通过引用传递的,我们不需要从调用中返回对象,只需访问调用者收集的消息。

【讨论】:

  • 我喜欢这个答案,但我不相信您不应该使用异常进行流控制的论点。为什么不?异常的传播是否允许某个级别的外部函数以最合适的方式从错误中恢复?我们几乎总是可以通过返回一个默认值来从我们没有预料到的事情中“恢复”,但是评估该返回值是否是有效调用的结果的逻辑由调用者决定。异常清楚地表明出现问题并传播到最合适的处理程序。请教我
  • @me232 异常表示发生了异常情况(不仅仅是错误)。验证失败(如上面的示例)并不例外。没有任何理由在异常处理过程中运行它。另见c2.com/cgi/wiki?DontUseExceptionsForFlowControlschlitt.info/opensource/blog/…
  • 我同意在您的示例中使用异常是毫无意义的,因为 false 的返回值可能就足够了。该功能似乎能够从问题本身中恢复。假设您有一个更复杂的示例,将一个对象转换为另一个对象。如果参数不适合转换,抛出异常是错误的吗?所有潜在的调用者都应该实现一些验证逻辑吗?
  • 我对此的政策是,如果您不希望首先使用某些参数调用函数,那么我很乐意使用异常来表明这一点,但我当然同意这将是一个在您实际期望发生的情况下使用它是一个糟糕且低效的想法
  • @me232 在您的转换示例中,情况可能很特殊。另一个例子是除以零。但是你有两个选择:抛出异常或返回SpecialCase
【解决方案2】:

在 PHP 中几乎一切皆有可能,因此实际上并没有最好的方法。

看看 php.net 上的 Exceptions http://php.net/manual/en/language.exceptions.php

【讨论】:

  • 我痛苦地了解到,对于每种语言,几乎一切皆有可能,这就是为什么设计模式让我们的生活更轻松,避免我们重新发明轮子并从其他人的经验中学习。官方文档从不谈论错误对象,这就是我问的原因。
猜你喜欢
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 2023-01-05
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多