代码之家  ›  专栏  ›  技术社区  ›  alex

什么时候最好在PHP中使用异常?

  •  3
  • alex  · 技术社区  · 15 年前

    我通常通过返回来指示方法中的错误 false ,但它并不总是与我的语义(取决于方法), 可能是有效的返回)。

    我已经研究过异常情况,想知道它们是一个一刀切的解决方案吗?我应该回来吗? 我还能在哪里?

    可以 这里完全没有重点,所以请你容忍我。

    // My old way
    function getProductById($id) {
    
        if ( ! is_numeric($id)) {
             return false;     
        }
    
    }
    
    // My consideration
    function getProductById($id) {
    
        if ( ! is_numeric($id)) {
             throw new Exception('The id must be numerical!');     
        }
    
    }
    
    4 回复  |  直到 10 年前
        1
  •  1
  •   alex    13 年前

    例外是伟大的!允许您将错误处理代码与错误代码分开。

    你说的没错 false 不能是函数的有效答案。如果你抛出一个错误,你也可以捕获它并做一些更有用的事情。

    当我说它有助于使您的错误处理代码远离错误时,请考虑一下

    try {    
        func1($a);  
        func2($b);  
        func3($c);  
    } catch (Exception $e) {  
        // error handling here  
    }  
    

    所以您不需要检查每个函数是否有错误的返回,并对其进行操作。

        2
  •  2
  •   DanMan    10 年前

    我的思路是:

    如果一段代码因为一个预条件失败而不能完成它的工作,那么抛出一个异常。

    所以,如果你 getProductById() 方法没有提供正确的值类型,因此无法执行它应该执行的操作,这是引发异常的原因。

    这使您能够更快地发现问题,因为“没有结果”和“可能无效的状态”之间有明显的区别。如果你习惯在这种情况下抛出一个异常,它会让你安心,因为它会很难失败,而不是以未定义/意外的方式继续。

    我会回来 false null 如果一切都按预期(如定义)工作,但过程没有找到匹配的产品。

    P.S.:这也是为什么根据我的定义,从输入验证中抛出异常是错误的。该代码的全部目的是验证输入,因此预期输入无效,因此也不例外。

        3
  •  0
  •   soulmerge    15 年前

    我建议只使用一种样式,所以如果到目前为止您已经通过返回false编写了应用程序,那么您应该考虑保持这种状态。

    但是,如果您想为异常重写代码,请注意在PHP中异常需要资源(在CPU时间和内存中)。我想举例说明:假设有一个函数 Product::getById($id) . 如果您希望此函数在未找到ID的情况下引发异常,则一切正常。但是,如果您想在单页请求中大量调用该函数并收集所有不存在的ID,那么您可能首先考虑在循环中捕获异常。这导致了一个巨大的减速。选项包括:

    • 复制代码(创建一个名为 Product::getByIdWithoutException() )
    • 为此用例创建专用函数( Product::getAllIds(array $ids) )这是最好的解决方案,但并不总是可行的(没有重写大量的代码,没有一个巨大的参数列表,或者没有打破软件工程的其他最佳实践等)。

    最后我切换到另一个模型,在那里我传递了一个参数来控制是否抛出异常。将默认值设置为true可以让我在不考虑此类错误情况的情况下懒散地编程,并且通过传递一个额外的参数,我可以将异常情况转换为速度。即使在其他函数中引发异常,也可以这样做,因为您可以将该参数传递给:

    function getById($id, $throwException = true) {
        if (!self::idExists($id)) {
            if ($throwException) {
                throw new IdNotFoundException();
            } else {
                return NULL;
            }
        }
        return self::getByWhereClause('id = ' . self::escape($id), $throwException);
    }
    

    我想你会发现这很有用。

        4
  •  0
  •   Noah Goodrich    15 年前

    乔尔·斯波斯基说, Exceptions shouldn't be used .

    关于异常处理,我的一般经验法则是,首先尝试为最终用户维护应用程序流,您可以首先通过从不在PHP中抛出异常来完成这一点,但有时它们是有用的。

    我倾向于看一个决定,是抛出异常,还是返回布尔值错误,还是基于可能导致触发问题的状态的条件,返回其他一些处理方法。

    当执行特定代码块时,这是一个正常的、合理的值还是状态?如果是这样,那么您可能只想返回一个布尔值false或其他一些指示代码块到达故障点的值。

    如果您担心可能存在非正常值或状态,或者如果值或状态是由于某人忘记正确初始化代码中的变量而导致的,那么异常可能是适当的,因为这将作为开发人员立即向您提供反馈。这里有两个例子,一个必需的属性必须在对象构造函数中设置,但该值没有正确指定,或者如果您有一个场景,在该场景中,不应对对象调用方法,则可能希望在调用该方法时引发异常。

    简而言之,我倾向于使用最适合的工具。如果我处理的是正常应用程序执行的一部分,那么我通常返回一个值来指示失败。如果发生了一些无效的情况,那么我抛出一个异常,以便处理这个问题。

    我想您可以说,我只使用异常来捕获那些应该真正停止最终用户的应用程序执行的东西,但是我在编写代码时考虑到,通过适当的测试,这些代码行中的任何一行都不应该在野外执行。

    推荐文章