PHP(或其他):处理不能发生的异常的策略"

时间:2016-02-23 19:51:57

标签: php exception exception-handling try-catch

请考虑以下代码。

class C {}

/**
 * @throws \InvalidArgumentException
 */
function classCreateInstance($class) {
  if (!is_string($class)) {
    throw new \InvalidArgumentException("Class name must be a string.");
  }
  if (!class_exists($class)) {
    throw new \InvalidArgumentException("Class '$class' does not exist.");
  }
  return new $class();
}

/**
 * @return C
 */
function foo() {
  return classCreateInstance(C::class);
}

有一个函数可能抛出异常,因为它对$class参数一无所知。

另一方面,主叫代码知道' C'是一个有效的类名,所以它想假设" InvalidArgumentException"永远不会发生。它希望避免使用详细的try / catch,并且希望避免使用自己的@throws标记。特别是如果它不被允许"拥有一个,因为它正在实现一个不注释异常的接口。

但是,从IDE /自动代码验证的角度来看,忽略此异常并不安全。

那么..处理异常的正确方法是什么?几乎不可能"从调用代码的角度来看?

1 个答案:

答案 0 :(得分:1)

在Java中。 "已检查"异常类和"未选中"异常类。只有已检查的异常是接口合同的一部分,而抛出一个未经检查的"即使接口没有声明它也允许异常。

在Java中,"永远不会发生"一个案例,一个人会抛出一个未经检查的例外 - 例如a" RuntimeException"。

在PHP中,这是基于约定的。方法可以抛出他们想要的任何例外。在文档注释中添加@throws标记很不错,但语言不强制执行。

但是,可以配置IDE或可能的其他代码审查工具,以根据已检查与未检查的异常的Java模型分析代码。

E.g。 PhpStorm可以选择不要求RuntimeException和LogicException的@throws doc标签。因此,这将允许将这些视为"未选中",然后编写自定义异常类并将其视为"已检查" Java中的例外。

PHP中的本机异常类:http://php.net/manual/en/spl.exceptions.php#spl.exceptions.tree 并非所有这些都继承自LogicException或RuntimeException,因此它们都将被视为"未选中"。只有根类Exception(和自定义子类)才会被视为"已检查"。

这种区别也意味着如果你调用没有声明/注释异常的方法/函数,你仍然需要考虑可以抛出异常。这可以包括在例如通过应用程序顶层的try / catch。 (例如index.php)