避免使用对Exception的静态访问

时间:2013-09-03 05:56:30

标签: php exception testing code-cleanup phpmd

我刚刚第一次启动PHPMD,可以预见的是,我有一个我无法弄清楚的错误。错误是

  

避免使用静态访问类'InvalidArgumentException'   方法'setLang'。

,代码是

public function setLang($val0) {
    switch ($val0) {
    case ENG:
    case FRE:
    case SPA;
        $this->lang = $val0;
        break;
    default:
        throw new InvalidArgumentException("Invalid language choice.");
    }
}

我尝试了各种不同的东西,但我认为在一天结束时Exception是一个静态工厂(???)所以它必须具有静态访问权限。但是,PHPMD的人肯定比我更聪明,所以这不会让他们感到害怕。

为什么会出现此警告,以及如何解决?

4 个答案:

答案 0 :(得分:10)

这个警告背后的想法是,如果你使用new关键字在代码中嵌入类名,那么在测试和模拟或存根方法中交换这些类将很难被测试的代码调用在他们。 PHPMD规则中的See the explanation

我认为在你的情况下这是误报,因为异常通常没有太多的行为,但它们的类名(以及它背后的类层次结构)几乎是唯一重要的事情。

如果您想在此处删除警告,可以在此处使用@SupressWarnings注释。

答案 1 :(得分:2)

啊,经过一些挖掘,我已经找到了答案,直接从马的嘴里。

位于yourphpdir\data\PHP_PMD\resources\rulesets的配置文件中,cleancode.xml有CDATA注释,说明了设置。

这个说:

  

静态访问会导致与其他类不可接受的依赖关系   导致难以测试代码。避免不惜一切代价使用静态访问   而是通过构造函数注入依赖项。唯一的情况   当静态访问是可接受的时候用于工厂方法。

解决它的方法是将异常作为参数传递,因此它在类之外声明。

$foo->setLang("Oh noes!", new InvalidArgumentException("No lang for you."));

答案 2 :(得分:0)

因为我使用了很多self :: for常量,所以更改phpmd代码以接受self :: and parent ::。

在第36行的PHP / PMD / Rule / CleanCode / StaticAccess.php程序中,更改为:

if ($this->isReferenceInParameter($reference)
    || $reference->getImage() === 'self' 
    || $reference->getImage() === 'parent' 
    ) {
    continue;
}

也许您可以使用它来优化代码。

答案 3 :(得分:0)

如果使用XML规则集,则可以从此规则中排除某些类(完整名称空间):

    <rule ref="rulesets/cleancode.xml">
        <exclude name="StaticAccess"/>
    </rule>
    <rule ref="rulesets/cleancode.xml/StaticAccess">
        <properties>
            <property name="exceptions" value="\Drupal\views\Views,\Drupal\Core\Access\AccessResult" />
        </properties>
    </rule>