为什么以及如何在此示例PHP代码中使用Exceptions?

Tow*_*wer 23 php error-handling exception-handling exception

我一直想知道为什么我会在PHP中使用Exceptions.我们来看一个简单的例子:

class Worker
{
 public function goToWork()
 {
  return $isInThatMood ?
  // Okay, I'll do it.
  true : 
  // In your dreams...
  false;
 }
}

$worker = new Worker;
if (!$worker->goToWork())
{
 if (date('l',time()) == 'Sunday')
  echo "Fine, you don't have to work on Sundays...";
 else
  echo "Get your a** back to work!";
}
else
 echo "Good.";
Run Code Online (Sandbox Code Playgroud)

我有理由对这种代码使用Exceptions吗?为什么?如何构建代码?

那些可能产生错误的代码呢:

class FileOutputter
{
 public function outputFile($file)
 {
  if (!file_exists($file))
   return false;
  return file_get_contents($file);
 }
}
Run Code Online (Sandbox Code Playgroud)

为什么我会在上述情况下使用例外?我有一种感觉,Exceptions可以帮助你识别出现的问题类型,是吗?

那么,我是否在此代码中正确使用了Exceptions:

class FileOutputter
{
 public function outputFile($file)
 {
  if (!file_exists($file))
   return throw new Exception("File not found.",123);
  try
  {
   $contents = file_get_contents($file);
  }
  catch (Exception $e)
  {
   return $e;
  }
  return $contents;
 }
}
Run Code Online (Sandbox Code Playgroud)

还是那么穷?现在底层代码可以这样做:

$fo = new FileOutputter;
try
{
 $fo->outputFile("File.extension");
}
catch (Exception $e)
{
 // Something happened, we could either display the error/problem directly
 echo $e->getMessage();
 // Or use the info to make alternative execution flows
 if ($e->getCode() == 123) // The one we specified earlier
  // Do something else now, create "an exception"
}
Run Code Online (Sandbox Code Playgroud)

还是我完全迷失在这里?

Rob*_*Rob 58

我什么时候应该使用例外?

您使用例外来表示异常情况; 也就是说,某种方法阻止某个方法履行其合同,而且不应该在该级别发生.

例如,您可能有一个方法,Record::save()它将记录的更改保存到数据库中.如果由于某种原因,无法完成此操作(例如,发生数据库错误或数据约束被破坏),则可能会抛出异常以指示失败.

如何创建自定义例外?

通常将例外命名为指示错误的性质,例如,DatabaseException.您可以Exception通过这种方式创建自定义命名异常,例如

class DatabaseException extends Exception {}
Run Code Online (Sandbox Code Playgroud)

(当然,您可以利用继承来为此异常提供一些其他诊断信息,例如连接详细信息或数据库错误代码.)

什么时候不应该使用例外?

考虑另一个例子; 检查文件是否存在的方法.如果文件不存在,这应该不会抛出异常,因为该方法的目的是执行所述检查.但是,打开文件并执行某些处理的方法可能会抛出异常,因为预期文件存在等等.

最初,并不总是清楚某些事情是什么并且不是例外.像大多数事情一样,随着时间的推移,经验会教会你何时应该而且不应该抛出异常.

为什么使用异常而不是返回特殊错误代码等?

关于异常的有用之处在于它们会立即跳出当前方法并抬起调用堆栈直到它们被捕获并处理,这意味着您可以将错误处理逻辑更高,尽管理想情况下不会太高.

通过使用清除机制来处理故障情况,当发生不良事件时,您会自动启动错误处理代码,这意味着您可以避免处理必须检查的各种魔术标记值,或者更糟糕的是,全局错误标记区分一堆不同的可能性.