1

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

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();

}

...或者也许您对异常有更多的想法?如何对付他们?帮我!=]

4

3 回答 3

2

一般来说,您只需要回显/记录异常,否则无法处理。这几乎意味着,如果您将整个应用程序放在try块中,则只有一个地方需要放置回显/日志记录逻辑(即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
}

log()上面的方法将检查是否启用了日志记录,以及是否将必要的数据保存到文件中。

于 2011-02-12T13:18:32.297 回答
2

应根据您发现的错误键入异常。Spl 异常是一个好的开始,但您确实应该创建自己的异常。我使用的一些常见的:

  • 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 块中异常的原因,您应该重新抛出它。让堆栈中您上面的代码尝试处理它。对于到处重复使用的库和类来说尤其如此。

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

另外,不要使用全局try{} catch() {}块。相反,安装一个异常处理程序来为您处理它。它更简洁,语义上更正确(因为 anytry{}catch{}意味着您知道如何处理捕获的异常,而异常处理程序恰好适用于由于您不知道如何处理而未处理的异常。

例外是针对特殊情况。不要将它们用于所有错误情况。如果用户提交的密码太短,不要抛出异常,在验证中处理。但是,如果您的散列函数预计sha256可用,但实际上不可用,那就是例外的时候了。异常对于程序错误(发生意外情况时,例如对函数的无效输入)、状态错误(当应用程序进入未知或不稳定状态时,例如请求的视图不存在时)和运行时错误(当应用程序遇到只能在运行时检测到的错误时,例如文件未找到错误)。

于 2011-02-12T14:03:45.970 回答
0

PHP 手册有一整页专门用于扩展异常,该页面还为您提供了有关识别文件/行号、回溯等方法的大量信息。抛出异常的位置。这是对调试非常有用的信息类型。

于 2011-02-12T13:22:12.420 回答