应根据您发现的错误键入异常。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;
}
}
至于您发布的示例代码,我会更改一些内容:
将抛出的异常更改为,InvalidArgumentException
因为它具有更多的语义含义(我几乎从不抛出原始异常)。
catch(Exception $e)
你应该不惜一切代价尽量避免。你不知道抛出了什么异常,那么你怎么可能处理它呢?
仅捕获您有理由确定您知道如何处理的异常(并且输出错误/日志记录不是处理,它正在消除异常的有用性)。你永远不应该看到类似catch($e) { logerror($e); }
或的东西,catch($e) { print $e->getMessage(); }
因为 netiher 实际上正在处理异常。
如果您不修复或解决您的 catch 块中异常的原因,您应该重新抛出它。让堆栈中您上面的代码尝试处理它。对于到处重复使用的库和类来说尤其如此。
现在,使用用户界面,捕获异常并向用户显示错误消息可能是可以接受的。因此,您打印异常消息的示例可能没问题,但您确实需要考虑它的用例。你是从模型还是控制器调用它?如果是这样,显示错误消息可能没问题。你是从图书馆调用它吗?如果是这样,最好让异常冒泡。
另外,不要使用全局try{} catch() {}
块。相反,安装一个异常处理程序来为您处理它。它更简洁,语义上更正确(因为 anytry{}catch{}
意味着您知道如何处理捕获的异常,而异常处理程序恰好适用于由于您不知道如何处理而未处理的异常。
例外是针对特殊情况。不要将它们用于所有错误情况。如果用户提交的密码太短,不要抛出异常,在验证中处理。但是,如果您的散列函数预计sha256
可用,但实际上不可用,那就是例外的时候了。异常对于程序错误(发生意外情况时,例如对函数的无效输入)、状态错误(当应用程序进入未知或不稳定状态时,例如请求的视图不存在时)和运行时错误(当应用程序遇到只能在运行时检测到的错误时,例如文件未找到错误)。