1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHP静的解析ツール PHPMD 個人的メモ

Last updated at Posted at 2022-11-22

PHPMD

PHPMD公式サイト

  • 考えられるバグ
  • 最適でないコード
  • 複雑すぎる表現
  • 未使用のパラメーター、メソッド、プロパティ

を通知してくれる
「最適でないコード」「複雑すぎる表現」あたりはPHPStanと差別化出来ているのかな。

# ./vendor/bin/phpmd [パス] [フォーマット] [オプション]

# example
./vendor/bin/phpmd app/Http/Controllers/TopController.php text codesize,design

インストール

composer require --dev phpmd/phpmd

composer以外でのインストール方法は公式サイトを参照してください

フォーマット

ターミナルで実行してみる分には個人が見やすい形式でOK。
PHPMD を組み込んでシェルでゴニョゴニョしたい場合は、扱いやすい形式でどうぞ。

オプション 説明
ansi ansi 形式で結果を出力
html html 形式で結果を出力
json json 形式で結果を出力
text text 形式で結果を出力
xml xml 形式で結果を出力

オプション

オプションはカンマ区切りで複数指定可能

# example
cleancode,codesize,design,naming
オプション 説明
cleancode クリーンなコードベースを強制するルール
codesize 循環的複雑度などコードサイズ関連部分を検出するルール
controversial キャメルケースなど議論の余地のある部分を検出するルール
design ソフトの設計関連の問題を検出するルール
naming 長すぎたり、短すぎたりする名前を検出するルール
unusedcode 使われていないコードを検出するルール

cleancode ルール説明

オプション 説明
BooleanArgumentFlag boolean フラグの引数は、単一責任原則 (SRP) に違反する場合の信頼できる指標となります。boolean フラグのロジックを独自のクラスやメソッドに抽出することで、この問題を解決することができます。
ElseExpression else分岐のあるif式は基本的に必要ない。条件を書き換えることで、else節が不要になり、コードがよりシンプルになります。そのためには、いくつかの小さなメソッドにコードを分割する必要があるかもしれませんが、早い段階でreturn文を使ってください。非常に単純な代入の場合、三項演算を使うこともできます。
StaticAccess 静的アクセスは、他のクラスと交換不可能な依存関係を引き起こし、テストしにくいコードにつながります。静的アクセスは絶対に避け、コンストラクタで依存性を注入するようにしましょう。静的アクセスが許容される唯一のケースは、ファクトリーメソッドに使用する場合です。
IfStatementAssignment if 節などでの代入は、コードの臭いとみなされます。PHPの代入は、右のオペランドを結果として返します。多くの場合、これは予期された動作ですが、特に右のオペランドがゼロやヌル、 あるいは空の文字列となる場合、発見が困難な多くのバグにつながる可能性があります。
DuplicatedArrayKey 配列リテラルで同じキーに対して別の値を定義すると、前のキー/値が上書きされるため、事実上未使用のコードとなります。もしキーが別の値を持つことが最初からわかっている場合は、通常、最初の値を定義する意味はありません。
MissingImport ファイルに含まれるすべての外部クラスをuse文によってインポートすることで、外部クラスを明確に表示することができます。
UndefinedVariable 以前に定義されていない変数が使用されたときに検出されます。
ErrorControlOperator エラーの抑制は可能な限り避けるべきです。なぜなら、単にエラーを抑制するだけでなく、発生が予測されないエラーも抑制してしまうからです。さらに、コードの実行速度が低下する可能性もあります。error_reporting() のレベルを変えるか、独自のエラーハンドラを設定することを検討してください。

codesize ルール説明

オプション 説明
CyclomaticComplexity 複雑さは、メソッド内の決定点の数にメソッドエントリーの数を加えた数で決まります。決定ポイントは、'if', 'while', 'for', 'case labels'です。一般に、1-4は低複雑度、5-7は中程度の複雑度、8-10は高複雑度、11+は非常に高い複雑度を示す。
NPathComplexity あるメソッドのNPath複雑度は、そのメソッドを通る非周期的な実行パスの数である。一般に、200の閾値は、複雑さを軽減するために対策を講じるべきポイントと考えられています。
ExcessiveMethodLength このルールに違反した場合、通常、そのメソッドの処理量が多すぎることを示します。ヘルパーメソッドを作成したり、コピー&ペーストしたコードを削除したりして、メソッドのサイズを小さくするようにしましょう。
ExcessiveClassLength 長いパラメータリストは、多数のパラメータをラップするために新しいオブジェクトを作成する必要があることを示す場合があります。基本的には、パラメータをグループ化するようにしましょう。
ExcessiveParameterList 長いパラメータリストは、多数のパラメータをラップするために新しいオブジェクトを作成する必要があることを示す場合があります。基本的には、パラメータをグループ化するようにしましょう。
ExcessivePublicCount クラス内に多数のパブリックメソッドや属性が宣言されている場合、そのクラスを徹底的にテストするために多くの労力が必要となるため、クラスを分割する必要がある可能性があることを示します。
TooManyFields フィールドが多すぎるクラスは、情報の一部をオブジェクトに入れ子にしてグループ化することで、より少ないフィールドに設計し直すことができます。例えば、city/state/zipフィールドを持つクラスは、代わりにAddressフィールドを1つ持つことができます。
TooManyMethods メソッドが多すぎるクラスは、おそらくリファクタリングの対象となり、その複雑さを軽減し、より細かいオブジェクトを持つ方法を見つけることができます。デフォルトでは、'get' や 'set' で始まるメソッドは無視されます。PHPMD 2.3 で、このデフォルトが 10 から 25 に変更されました。
TooManyPublicMethods パブリックメソッドが多すぎるクラスは、おそらくリファクタリングの対象となり、その複雑さを軽減し、より細かいオブジェクトを持つ方法を見つけることができます。デフォルトでは、'get' や 'set' で始まるメソッドは無視されます。
ExcessiveClassComplexity クラスの Weighted Method Count (WMC) は、このクラスを修正・維持するためにどれだけの時間と労力が必要かを示す良い指標となります。WMC メトリクスは、クラスで宣言されているすべてのメソッドの複雑さの合計として定義されます。メソッドの数が多いということは、このクラスが派生クラスに対してより大きな影響を与える可能性があることも意味します。

controversial ルール説明

オプション 説明
Superglobals スーパーグローバル変数に直接アクセスすることは、バッドプラクティスであると考えられています。これらの変数は、例えばフレームワークで提供されるオブジェクトにカプセル化されるべきです。
CamelCaseClassName クラス名にはCamelCase記法を使用するのがベストプラクティスとされています。
CamelCasePropertyName 属性の命名にはキャメルケース表記を使用するのがベストプラクティスとされています。
CamelCaseMethodName メソッドの命名にはキャメルケース表記を用いるのがベストプラクティスとされています。
CamelCaseParameterName パラメータ名にはキャメルケース表記を使用するのがベストプラクティスとされています。
CamelCaseVariableName 変数名にはキャメルケース表記を使用するのがベストプラクティスとされています。

design ルール説明

オプション 説明
ExitExpression 通常のコード内の終了式はテスト不可能であるため、避けるべきである。終了式を何らかの起動スクリプトに移動して、エラー/例外コードを呼び出し環境に返すことを検討してください。
EvalExpression eval-expressionはテスト不可能であり、セキュリティリスクであり、バッドプラクティスです。したがって、避けるべきです。eval 式を通常のコードに置き換えることを検討してください。
GotoStatement Gotoはコードを読みにくくし、この言語構造を使用するアプリケーションの制御フローを理解することはほぼ不可能です。したがって、これは避けるべきです。Gotoを、より読みやすい通常の制御構造や分離したメソッド/関数に置き換えることを検討してください。
NumberOfChildren 子クラスの数が多すぎるクラスは、クラス階層のバランスが悪いことを示す指標です。このクラス階層をリファクタリングすることを検討する必要があります。
DepthOfInheritance 依存関係が強すぎるクラスは、クラスのいくつかの品質面に悪影響を及ぼします。これには、安定性、保守性、理解しやすさなどの品質基準が含まれます。
CouplingBetweenObjects 依存関係が強すぎるクラスは、クラスのいくつかの品質面に悪影響を及ぼします。これには、安定性、保守性、理解しやすさなどの品質基準が含まれます。
DevelopmentCodeFragment ar_dump()、print_r()などの関数は通常、開発時にのみ使用されるため、実運用コードでこのような呼び出しがあるのは、単に忘れられただけという良い指標になります。
EmptyCatchBlock 通常、空の try-catch は悪い考えです。なぜなら、エラー条件を黙って飲み込み、実行を続行するからです。時にはこれが正しい場合もありますが、多くの場合、開発者が例外を発見し、それに対して何をすべきかがわからず、問題を解決するために空のキャッチを使用したことの表れなのです。
CountInLoopExpression ループの式で count/sizeof を使用することはバッドプラクティスであり、特にループが配列を操作する場合、count が反復するたびに発生するため、多くのバグの原因となる可能性があります。

naming ルール説明

オプション 説明
LongClassName クラスやインターフェースが過度に長い名前で宣言されている場合に検出します。
ShortClassName クラスやインターフェースの名前が非常に短い場合に検出されます。
ShortVariable フィールド、ローカル、パラメーターが非常に短い名前である場合に検出します。
LongVariable フィールド、形式変数、ローカル変数が長い名前で宣言されている場合に検出されます。
ShortMethodName 非常に短いメソッド名が使用されている場合に検出されます。
ConstructorWithNameAsEnclosingClass コンストラクタのメソッド名は、クラス名と同じであってはなりません。
ConstantNamingConventions クラス/インターフェースの定数名は、常に大文字で定義する必要があります。
BooleanGetMethodName getX()' という名前のメソッドで、戻り値の型が 'boolean' であるものを探します。慣習として、これらのメソッドには 'isX()' あるいは 'hasX()' という名前をつけることになっています。

unusedcode ルール説明

オプション 説明
UnusedPrivateField プライベートフィールドが宣言され、かつ/または値が割り当てられているが、使用されていない場合を検出する。
UnusedLocalVariable ローカル変数が宣言または割り当てられたが、使用されていないことを検出します。
UnusedPrivateMethod 未使用のプライベートメソッド:プライベートメソッドが宣言されているが、使用されていない場合に検出されます。
UnusedFormalParameter メソッドやコンストラクタにパラメータを渡して、そのパラメータを使用しないことは避けてください。

カスタムルールセット

上記の中で使いたいルールだけを組み込んで実行していくのが正しい使い方っぽい。
下記ディレクトリにデフォルトのルールセットが格納されています

# ls vendor/phpmd/phpmd/src/main/resources/rulesets/

cleancode.xml
codesize.xml
controversial.xml
design.xml
naming.xml
unusedcode.xml

デフォルトファイルをどこか適当なプロジェクトディレクトリ内に複製して、使用したくないルールは削除した上でオプションに指定していく.

# ディレクトリ作成
mkdir phpmd/
# copy
cp vendor/phpmd/phpmd/src/main/resources/rulesets/* phpmd/

# example
./vendor/bin/phpmd app/Http/Controllers/TopController.php text phpmd/creancode.xml,phpmd/codesize.xml
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?