考虑这个方便的小类:
class FunkyFile {
private $path;
private $contents = null;
public function __construct($path) {
$this->setPath($path);
}
private function setPath($path) {
if( !is_file($path) || !is_readable($path) )
throw new \InvalidArgumentException("Hm, that's not a valid file!");
$this->path = realpath($path);
return $this;
}
public function getContents() {
if( is_null($this->contents) ) {
$this->contents = @file_get_contents( $this->path );
if($this->contents === false)
throw new \Exception("Hm, I can't read the file, for some reason!");
}
return $this->contents;
}
}
这是对异常的完美使用。从FunkyFile's
角度来看,如果路径无效或file_get_contents
失败,则绝对无法采取任何措施来纠正这种情况。真正的例外情况;)
但是,让用户知道您在代码中的某个地方偶然发现了错误的文件路径,是否有任何价值?例如:
class Welcome extends Controller {
public function index() {
/**
* Ah, let's show user this file she asked for
*/
try {
$file = new File("HelloWorld.txt");
$contents = $file->getContents();
echo $contents;
} catch(\Exception $e) {
log($e->getMessage());
echo "Sorry, I'm having a bad day!";
}
}
}
除了告诉别人您今天过得很糟糕之外,您还可以选择:
倒退
您还有另一种获取信息的方式吗?在上面的简单示例中,这似乎不太可能,但是请考虑主/从数据库模式。主机可能没有响应,但也许,也许,从机仍然在那里(反之亦然)。
是用户的错吗?
用户是否提交了错误的输入?好吧,告诉她。您可以吠叫错误消息,也可以友好地将错误消息与表单一起使用,以便她可以键入正确的路径。
是你的错吗
对您而言,我的意思是不是用户的任何东西,范围从您输入错误的文件路径到服务器中出现问题。严格来说,是时候出现503 HTTP错误了,因为该服务不可用。CI具有show_404()
功能,可以轻松构建show_503()
。
忠告,您应该考虑流氓异常。CodeIgniter是一段凌乱的代码,您永远不知道何时会弹出异常。同样,您可能会忘记自己的异常,最安全的选择是实现一个捕获所有异常处理程序。在PHP中,您可以使用set_exception_handler来做到这一点:
function FunkyExceptionHandler($exception) {
if(ENVIRONMENT == "production") {
log($e->getMessage());
show_503();
} else {
echo "Uncaught exception: " , $exception->getMessage(), "\n";
}
}
set_exception_handler("FunkyExceptionHandler");
您还可以通过set_error_handler处理流氓错误。您可以编写与异常相同的处理程序,或者将所有错误都转换为ErrorException
并让您的异常处理程序处理它们:
function FunkyErrorHandler($errno, $errstr, $errfile, $errline) {
// will be caught by FunkyExceptionHandler if not handled
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("FunkyErrorHandler");