Rules Overview¶
Qualimetrix ships with a set of built-in rules that check your PHP code for common quality problems. Each rule looks at a specific aspect of your code -- complexity, size, coupling, design, maintainability, or common bad practices -- and reports violations when thresholds are exceeded.
Severity Levels¶
Every violation has one of two severity levels:
- Warning -- the code is getting harder to maintain. You should consider refactoring, but it is not critical yet.
- Error -- the code has crossed a threshold where it is likely to cause real problems: bugs, difficulty testing, or resistance to change. This needs attention.
You can customize all thresholds via configuration file or command-line options.
Rules Summary¶
Complexity Rules¶
These rules measure how tangled and branching your code is. Complex code is harder to understand, test, and change safely.
| Rule | ID | What it checks | Default Warning | Default Error |
|---|---|---|---|---|
| Cyclomatic Complexity | complexity.cyclomatic |
Number of decision paths in a method | 10 (method) | 20 (method) |
| Cognitive Complexity | complexity.cognitive |
How hard the code is to understand | 15 (method) | 30 (method) |
| NPath Complexity | complexity.npath |
Total number of possible execution paths | 200 (method) | 1000 (method) |
| WMC | complexity.wmc |
Total complexity of all methods in a class | 50 | 80 |
Read more about Complexity rules -->
Size Rules¶
These rules check whether your classes and namespaces have grown too large. Big classes tend to do too many things at once.
| Rule | ID | What it checks | Default Warning | Default Error |
|---|---|---|---|---|
| Method Count | size.method-count |
Number of methods in a class | 20 | 30 |
| Class Count | size.class-count |
Number of classes in a namespace | 15 | 25 |
| Property Count | size.property-count |
Number of properties in a class | 15 | 20 |
Read more about Size rules -->
Design Rules¶
These rules check class cohesion, inheritance depth, and structural problems.
| Rule | ID | What it checks | Default Warning | Default Error |
|---|---|---|---|---|
| LCOM | design.lcom |
Whether a class does too many unrelated things | 3 | 5 |
| Inheritance Depth | design.inheritance |
How deep the inheritance chain is | 4 | 6 |
| NOC | design.noc |
Number of classes inheriting from this one | 10 | 15 |
| Type Coverage | design.type-coverage |
Percentage of typed parameters, returns, properties | 80% (below) | 50% (below) |
| Data Class | design.data-class |
High public surface but low complexity | Warning | -- |
| God Class | design.god-class |
Overly complex, large classes with low cohesion | 3+ criteria | all criteria |
Read more about Design rules -->
Cohesion Rules¶
These rules measure how well the methods inside a class work together. Low cohesion indicates a class is doing too many unrelated things.
| Metric | ID | What it checks | Recommended |
|---|---|---|---|
| TCC | tcc |
Fraction of public method pairs sharing properties | >= 0.5 |
| LCC | lcc |
Fraction including transitive connections | >= 0.5 |
Note
TCC and LCC are metrics, not rules. They cannot be enabled or disabled via --disable-rule / --only-rule, and do not generate violations. They appear in reports as informational values and are used by the God Class rule as inputs.
Read more about Cohesion rules -->
Coupling Rules¶
These rules measure how tightly your classes depend on each other. Tightly coupled code is fragile -- a change in one place can break many others.
| Rule | ID | What it checks | Default Warning | Default Error |
|---|---|---|---|---|
| CBO | coupling.cbo |
Total number of dependencies | 14 | 20 |
| Instability | coupling.instability |
How much a class depends on others vs others depend on it | 0.8 | 0.95 |
| Distance | coupling.distance |
Balance between abstractness and stability | 0.3 | 0.5 |
| ClassRank | coupling.class-rank |
Critical hub classes via PageRank algorithm | 0.02 | 0.05 |
Read more about Coupling rules -->
Maintainability Rules¶
| Rule | ID | What it checks | Default Warning | Default Error |
|---|---|---|---|---|
| Maintainability Index | maintainability.index |
Overall code maintainability score | <40 | <20 |
Read more about Maintainability rules -->
Architecture Rules¶
| Rule | ID | What it checks | Default Warning | Default Error |
|---|---|---|---|---|
| Circular Dependencies | architecture.circular-dependency |
Classes that depend on each other in a loop | -- | Error |
Read more about Architecture rules -->
Duplication Rules¶
These rules detect duplicated code blocks across your codebase using token-stream analysis.
| Rule | ID | What it detects | Default Warning | Default Error |
|---|---|---|---|---|
| Code Duplication | duplication.code-duplication |
Structurally identical code blocks across files | < 50 lines | >= 50 lines |
Read more about Duplication rules -->
Code Smell Rules¶
These rules detect common bad practices that are almost always wrong, regardless of context. Most produce an Error severity by default.
| Rule | ID | What it detects |
|---|---|---|
| Boolean Argument | code-smell.boolean-argument |
bool parameters in method signatures |
| Count in Loop | code-smell.count-in-loop |
Calling count() in a loop condition |
| Debug Code | code-smell.debug-code |
var_dump, print_r, debug_backtrace, etc. |
| Empty Catch | code-smell.empty-catch |
catch blocks with no body |
| Error Suppression | code-smell.error-suppression |
The @ error suppression operator |
| Eval | code-smell.eval |
Use of eval() |
| Exit | code-smell.exit |
Use of exit() or die() |
| Goto | code-smell.goto |
Use of goto |
| Superglobals | code-smell.superglobals |
Direct access to $_GET, $_POST, etc. |
| Long Parameter List | code-smell.long-parameter-list |
Methods with too many parameters |
| Unreachable Code | code-smell.unreachable-code |
Code after return/throw/exit statements |
| Identical Sub-expression | code-smell.identical-subexpression |
Identical operands, duplicate conditions, same ternary branches |
| Constructor Over-injection | code-smell.constructor-overinjection |
Too many constructor dependencies |
| Unused Private | code-smell.unused-private |
Unused private methods, properties, constants |
Read more about Code Smell rules -->
Security Rules¶
These rules detect patterns that may introduce security vulnerabilities.
| Rule | ID | What it detects |
|---|---|---|
| Hardcoded Credentials | security.hardcoded-credentials |
Passwords, API keys, tokens in code |
| SQL Injection | security.sql-injection |
Superglobals in SQL queries |
| XSS | security.xss |
Unsanitized superglobals in echo/print |
| Command Injection | security.command-injection |
Superglobals in shell functions |
| Sensitive Parameter | security.sensitive-parameter |
Missing #[\SensitiveParameter] attribute |
Read more about Security rules -->
Disabling Rules¶
You can disable individual rules or entire groups:
# Disable a single rule
bin/qmx check src/ --disable-rule=complexity.npath
# Disable an entire group (prefix matching)
bin/qmx check src/ --disable-rule=code-smell
Excluding Namespaces¶
Any rule supports exclude_namespaces to suppress violations from specific namespaces (prefix matching). The files are still analyzed and metrics are collected, but violations are not reported:
This is useful for test code, generated code, or legacy modules that you want to keep in metrics but exclude from violation reports for a specific rule.
Customizing Thresholds¶
Override any threshold via the command line:
bin/qmx check src/ --rule-opt="complexity.cyclomatic:method.warning=15"
bin/qmx check src/ --rule-opt="size.method-count:warning=25"
Or in your qmx.yaml configuration file: