11

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

避免在方法“setLang”中使用对类“InvalidArgumentException”的静态访问。

代码是

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

4 回答 4

12

这个警告背后的想法是,如果你在代码中嵌入类名和new关键字,那么在测试和模拟或存根方法中替换这些类是很困难的,被测代码可能会调用它们。请参阅PHPMD 规则中的说明。

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

如果您想摆脱此处的警告,可以使用@SupressWarnings此处的注释。

于 2013-09-03T06:03:48.160 回答
2

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

在位于 的配置文件中,yourphpdir\data\PHP_PMD\resources\rulesetscleancode.xml解释设置的 CDATA 注释。

这个说:

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

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

$foo->setLang("Oh noes!", new InvalidArgumentException("No lang for you."));
于 2013-09-03T06:15:55.903 回答
0

因为我大量使用 self:: 作为常量,所以将 phpmd 代码更改为接受 self:: 和 parent::。

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

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

也许您可以使用它来改进代码。

于 2014-05-25T15:37:13.990 回答
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>
于 2020-07-30T06:10:41.527 回答