PHPMD - PHP Mess Detector
等價(jià)于java工具PMD闰渔,能夠?qū)hp 源代碼進(jìn)行如下問題檢測(cè):
- 可能的bug
- 欠佳的代碼
- 過于復(fù)雜的表達(dá)式
- 未使用的方法罩抗、變量窍荧、參數(shù)、屬性
最新版本發(fā)布于 2021/05/11
基本使用
phpmd /path/to/source text codesize
- 第一個(gè)參數(shù) 要檢測(cè)的代碼地址
- 第二個(gè)參數(shù)指定輸出檢測(cè)結(jié)果的格式
- 第三個(gè)參數(shù)是指定的規(guī)則集
規(guī)則集合
-
Clean Code
: 一些包含clean code的規(guī)則集合殊者,包括面向?qū)ο笤O(shè)計(jì)的 SOLID(單一功能与境、開閉原則、里氏替換猖吴、接口隔離以及依賴反轉(zhuǎn))原則摔刁。 -
Code Size
: 有關(guān)代碼大小的相關(guān)問題,例如行數(shù)等 -
Controversial
: 具有爭議的規(guī)則海蔽,可以不參考此規(guī)則 -
Design
: 設(shè)計(jì)規(guī)則共屈,包含類依賴數(shù)量等等 -
Naming
: 命名規(guī)則 -
Unused Code
: 未使用代碼規(guī)則
關(guān)于clean code
有一本書名就叫 << Clean Code >>,個(gè)人讀下來感受頗深绑谣。
這里主要介紹一些我認(rèn)為非常有必要注意的規(guī)則
Clean Code
BooleanArgumentFlag
布爾標(biāo)志參數(shù)違反單一責(zé)任原則(SRP),可以將此類方法一拆為二。
class Foo {
public function drink($thirsty = true) {
if($thirsty){
// 喝2杯
}else{
// 喝一杯
}
}
}
class Foo {
public function drinkThirsty() {
// 喝2杯
}
public function drinkUnThirsty() {
// 喝2杯
}
}
ElseExpression
class Foo
{
public function bar($flag)
{
if ($flag) {
// one branch
} else {
// another branch
}
}
}
像這樣的if else的表達(dá)式其實(shí)是沒必要的拗引,可通過三元表達(dá)式借宵、拆分方法或者可能的情況下先return來規(guī)避這類問題,以將代碼簡單或增加可讀性矾削。
class Foo
{
public function bar($flag)
{
if ($flag) {
// one branch
return
}
// another branch
}
}
Code Size
CyclomaticComplexity
圈復(fù)雜度壤玫,用來衡量代碼復(fù)雜度的一個(gè)計(jì)算規(guī)則。復(fù)雜度越高代表代碼可讀性哼凯、可維護(hù)性越差垦细,易錯(cuò)性更高、集成測(cè)試更難挡逼。
點(diǎn)邊計(jì)算法
上述表達(dá)式的圈復(fù)雜度為 e = 10 n = 8 Cyclomatic Complexity = 10 - 8 + 2 = 4
計(jì)算公式為:
V(G) = E - N + 2
其中,e表示控制流圖中邊的數(shù)量腻豌,n表示控制流圖中節(jié)點(diǎn)的數(shù)量家坎。
更多可參考 http://kaelzhang81.github.io/2017/06/18/詳解圈復(fù)雜度/
ExcessiveMethodLength
方法長度,該規(guī)則有2個(gè)屬性
minimum 最小限定值 默認(rèn) 100
ignore-whitespace 是否忽略空白行 默認(rèn) false
ExcessiveClassLength
類長度
minimum 最小限定值 默認(rèn) 1000
ignore-whitespace 是否忽略空白行 默認(rèn) false
ExcessiveParameterList
參數(shù)個(gè)數(shù)限定
minimum 10吝梅,根據(jù)《clean code》一書的說法虱疏,這個(gè)值應(yīng)該限定為3
ExcessivePublicCount
公共方法、公共屬性
minimum 45
TooManyFields
maxfields 15
TooManyMethods
maxmethods 25
ignorepattern (^(set|get))i
TooManyPublicMethods
maxmethods 10 The method count reporting threshold
ignorepattern (^(set|get))i
自定義規(guī)則
有的默認(rèn)規(guī)則也許并不能滿足自身需求需做舍棄或修改苏携。例如函數(shù)參數(shù)數(shù)做瞪,在《clean code》一書中定義的是最多為3,而phpmd默認(rèn)指定的是10. 10個(gè)確實(shí)已經(jīng)非常難看了右冻,想象你去調(diào)用一個(gè)有10個(gè)參數(shù)的函數(shù)装蓬,你一定會(huì)吐槽懵逼的。
好在phpmd這些都可以修改纱扭,如下:
- 引入unusedcode規(guī)則集
- 引入codesize,并暫時(shí)排除
NPathComplexity
和CyclomaticComplexity
這兩個(gè)理解起來有一定困難的規(guī)則牍帚。誠然CyclomaticComplexity
在度量復(fù)雜度十分有效,但若你的所有函數(shù)已經(jīng)滿足ExcessiveMethodLength
已經(jīng)進(jìn)步很大了乳蛾,所以一步步來暗赶。 - 修改ExcessiveParameterList,讓限定值為3.
- 修改ExcessiveMethodLength和ExcessiveClassLength,忽略空白行
- 排除StaticAccess規(guī)則
<?xml version="1.0"?>
<ruleset name="My first PHPMD rule set"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="
http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
My custom rule set that checks my code...
</description>
<rule ref="rulesets/unusedcode.xml" />
<rule ref="rulesets/codesize.xml">
<exclude name="ExcessiveParameterList" />
<exclude name="NPathComplexity"/>
<exclude name="CyclomaticComplexity"/>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveParameterList">
<properties>
<property name="minimum">
<value>
3
</value>
</property>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveClassLength">
<properties>
<property name="ignore-whitespace">
<value>
true
</value>
</property>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength">
<properties>
<property name="ignore-whitespace">
<value>
true
</value>
</property>
</properties>
</rule>
<rule ref="rulesets/cleancode.xml">
<exclude name="StaticAccess" />
</rule>
</ruleset>
博客內(nèi)容遵循 署名-非商業(yè)性使用-相同方式共享 4.0 國際 (CC BY-NC-SA 4.0) 協(xié)議