类抛出除成功以外的任何异常,这是一个很好的实践/编程形式吗?


Class throwing exceptions for anything other than success, is it a good practice/programming form?

我正在编写一些类,想知道如何正确处理不成功的场景。例如,文件上传类,作为参数接受 $_FILES 资源的名称:

class FileUpload {
    private $file;
    public function __construct($file) {
        $this->file = $file;
    }
    public function upload() {
        if (!isset($_FILES[$this->file])) { 
            throw new Exception("Reference to non existent resource.");
        }
        if ($_FILES[$this->file]['error'] !== 0) { 
            throw new Exception("Resource indicates error.");
        }
                // All other sorts of checks here, like security checks,
                // and then finally moving of the file to it's final destination
    }
}

这是正确的形式吗?我的想法是这样的:当开发人员创建一个新的FileUpload实例时,他的意图要么是上传文件,要么知道为什么没有上传文件,而这个类会给他这个。也:

1) 真(文件经过正确格式测试,安全性检查,如果它是图像,甚至可能进一步处理,现在它正是您想要的位置。简而言之 - 你想要的一切都解决了)

2)异常(出了点问题,消息让你确切地知道是什么,所以你可以处理它。

如果这一切都很好,我应该只使用带有自定义消息的异常,还是为所有内容创建自定义异常,例如 WrongMimeType?

如果这很重要 - 类将是开源的,可供所有人使用,所以从这个方面我也想使它们尽可能标准化,开发人员友好并易于插入现有软件。

这可能应该移到代码审查中,因为在我看来,这是一个关于编码风格的问题。

然而:

您的upload()方法设计得很糟糕。它应该接受一个参数,而不是从$_FILES中获取数据 - 外部用户应该将其传递给函数。通常,任何类都不应从超全局变量或全局变量中获取数据。

尊重这一点会消除抛出异常的第一个原因。 :)

然后?进一步讨论细节有点困难,因为没有太多代码可看,所以我回到一般评论:

不应将例外用作goto的替代品。它们应该标志着无法预料的特殊状态。

验证表单时,无效表单数据不是无法预料的异常状态 - 它是两种常见情况之一。实际上,您正在验证类中的表单数据 - 如果表单无效,则不应引发异常。

另一件事:不要在异常消息中隐藏出错的事情。如果我无法捕获使用多个 catch 语句抛出的不同异常类,但必须查看消息,那么使用该类就会变得更加困难。

而且因为您正在询问如何使该代码可供其他人使用:使用命名空间、与 PSR-0 兼容的自动加载和您自己的异常类。并且不要从超全局变量中获取数据。

相关文章: