我刚刚第一次启动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的人肯定比我聪明,所以这不会让他们担心。
为什么存在此警告,以及如何解决?
此警告背后的思想是,如果使用new
关键字将类名嵌入到代码中,则很难在测试中交换这些类以及被测试代码可能调用的mock或stub方法。请参阅PHPMD规则中的说明。
我认为在您的情况下,这是误报,因为异常通常本身没有太多行为,但它们的类名(及其背后的类层次结构)几乎是它们唯一重要的东西。
如果你想去掉这里的警告,你可以在这里使用@SupressWarnings
注释。
啊,经过一番挖掘,我直接从马嘴里找到了答案。
在位于yourphpdir'data'PHP_PMD'resources'rulesets
的配置文件中,cleancode.xml
具有CDATA注释,用于解释设置。
这个上面写着:
静态访问导致对其他类和导致难以测试代码。不惜一切代价避免使用静态访问而是通过构造函数注入依赖项。唯一的案例当静态访问可接受时,是用于工厂方法时。
解决它的方法就是将异常作为参数传递,这样它就在类之外声明了。
$foo->setLang("Oh noes!", new InvalidArgumentException("No lang for you."));
因为我使用了很多self::作为常量,所以更改phpmd代码以接受self:和parent:。
在第36行的PHP/PMD/Rule/CleanCode/StaticAccess.PHP程序中,更改为:
if ($this->isReferenceInParameter($reference)
|| $reference->getImage() === 'self'
|| $reference->getImage() === 'parent'
) {
continue;
}
也许您可以使用它来完善代码。
如果使用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>