PHP中的例外情况。怎么用?如何扩展他们?

时间:2011-02-12 13:09:06

标签: php custom-exceptions

几天前我处理这样的错误......

exit( 'Error!' );

or exit( 'Error!' );
是的,对吗? =]现在我正在尝试学习例外。这是我有多远......

http://pastie.org/1555970

这是正确使用它们吗?我可以获得关于他们的更多信息,这很酷。像抛出异常的文件和该文件的行。我知道有内置方法(在Exception类中),但我想以某种方式扩展它,所以我不需要写...

throw new My_Exception( '...' );

catch( My_Exception $e ) {

  echo $e->my_method();

}

...但使用旧语法。

throw new Exception( '...' );

catch( Exception $e ) {

  echo $e->getMessage();

}

...或者你对异常有更深刻的想法?怎么处理他们?帮我! =]

3 个答案:

答案 0 :(得分:2)

通常,您只需要回显/记录异常,这些异常无法以其他方式处理。这几乎意味着,如果将整个应用程序放在try块中,则只需要放置一个回显/记录逻辑的位置(即与最外层{{1}相关联的catch块。 })。

另一方面,如果可以在不停止应用程序的情况下处理异常(在您的示例中,这可能是提供默认数值,而不是不正确的值),那么通常不需要回显/记录它。

如果您确实要记录此类异常(例如,用于调试),那么您的应用程序应该包含一个日志记录框架,这样就足以在您的try块中执行类似

的操作
catch
上面的

} catch (Exception $e) { ExceptionLogger::log($e); //static method == ugly, but it's for simplicity in this example // do whatever needs to be done } 方法会检查是否启用了日志记录,以及是否将必要的数据保存到文件中。

答案 1 :(得分:2)

应根据您找到的错误输入例外情况。 Spl Exceptions是一个好的开始,但你也应该创建自己的例外。我使用的一些常见的:

  • FileNotFoundException extends RuntimeException< - 自我解释
  • HTTPException extends RuntimeException< - 遇到非200结果时用于http类
  • DatabaseQueryException extends LogicException< - 用于数据库查询错误

现在,通过专门输入它们,它可以让您处理代码中的错误。因此,假设您要获取HTTP资源。如果除了404之外的任何内容失败,您想尝试备份URL。你可以这样做:

try {
    return getHttp($url1):
} catch (HttpException $e) {
    if ($e->getCode() != 404) {
        try {
            return getHttp($url2);
        } catch (HttpException $e2) {
            //It's ok to ignore this, since why know it's an HTTP error and not something worse
            return false;
        }
    } else {
        return false;
    }
}

就您发布的示例代码而言,我会更改一些内容:

  1. 将抛出的异常更改为InvalidArgumentException,因为它具有更多的语义含义(我几乎从不抛出原始异常)。

  2. 您应该不惜一切代价避免catch(Exception $e)。你不知道抛出了什么异常,那你怎么可能处理呢?

  3. 只捕获您确定知道如何处理的异常(并且输出错误/日志记录不处理,它会消除异常的用处)。您应该从不查看catch($e) { logerror($e); }catch($e) { print $e->getMessage(); }之类的内容,因为netiher实际上是处理异常。

  4. 如果你没有修复解决方法你的catch块中的异常原因,你应该重新抛出它。让堆栈上方的代码尝试处理它。对于遍布整个地方的库和类,尤其如此。

    现在,使用用户界面,可以接受异常并向用户显示错误消息。因此,您打印异常消息的示例可能没问题,但您确实需要考虑它的用例。你是从模型或控制器调用它吗?如果是这样,可能会显示错误消息。你是从图书馆打电话吗?如果是这样,最好让异常泡沫化。

  5. 此外,请勿使用全局try{} catch() {}块。而是安装Exception Handler来为您处理它。它更干净,语义更正确(因为任何try{}catch{}意味着您知道如何来处理您捕获的异常,而异常处理程序正是针对未处理的异常你不知道如何处理它们。

    例外情况适用于特殊情况。不要在所有错误情况下使用它们。如果用户提交的密码太短,请不要抛出异常,请在验证时处理。但是如果你的哈希函数期望sha256可用而不是,那就是异常的时间。异常对程序错误很有用(当出现意外情况时,例如函数输入无效),状态错误(当应用程序进入未知或不稳定的状态时,例如请求的视图不存在)和运行时错误(当应用程序遇到只能在运行时检测到的错误时,例如文件未找到错误)。

答案 2 :(得分:0)

PHP手册的整个页面专门用于extending exceptions,该页面还提供了很多关于识别文件/行号,回溯等方法的信息,其中引发了异常。这是对调试非常有用的信息类型。