haspadar / phpstan-rules
PHPStan design rules for immutability and structure
Package info
github.com/haspadar/phpstan-rules
Type:phpstan-extension
pkg:composer/haspadar/phpstan-rules
Requires
- php: >=8.3
- phpstan/phpstan: ^2.0
Requires (Dev)
- haspadar/piqule: dev-main
- kubawerlos/php-cs-fixer-custom-fixers: ^3.36
- slevomat/coding-standard: ^8.28
- dev-main
- v0.30.3
- v0.30.2
- v0.30.1
- v0.30.0
- v0.29.0
- v0.28.0
- v0.27.2
- v0.27.1
- v0.27.0
- v0.26.0
- v0.25.1
- v0.25.0
- v0.24.0
- v0.23.0
- v0.22.0
- v0.21.0
- v0.20.0
- v0.19.0
- v0.18.0
- v0.17.0
- v0.16.1
- v0.16.0
- v0.15.0
- v0.14.1
- v0.14.0
- v0.13.0
- v0.12.0
- v0.11.0
- v0.10.0
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.0
- v0.5.1
- v0.5.0
- v0.4.0
- v0.3.0
- v0.2.0
- v0.1.0
- dev-variable-name-rule
- dev-fix-codecov-coverage
- dev-abbreviation-rule
- dev-update-piqule-envs
- dev-update-piqule
- dev-no-inline-comment-rule
- dev-class-length-rule
- dev-cognitive-complexity-rule
- dev-forbid-line-comment-before-declaration
- dev-class-constant-type-hint-rule
- dev-suppress-psalm-unused-method
- dev-upgrade-piqule
- dev-no-phpdoc-for-overridden
- dev-phpdoc-missing-class
- dev-upgrade-piqule-slevomat
- dev-param-description-capital
- dev-return-description-capital-readonly
- dev-return-description-capital
- dev-phpdoc-missing-property
- dev-phpdoc-missing-method
- dev-expose-rule-parameters
- dev-atclause-order
- dev-phpdoc-capitalization
- dev-phpdoc-empty-rule
- dev-update-readme-rules
- dev-fix-sonarcloud-return-count
- dev-phpdoc-punctuation-rule
- dev-upgrade-piqule-strict-rules
- dev-modified-control-variable
- dev-inner-assignment-rule
- dev-fix-cyclomatic-checked-exception
- dev-forbid-broad-throws
- dev-forbid-broad-exception-catch
- dev-forbid-parameter-reassignment
- dev-constructor-only-initializes
- dev-no-public-static
- dev-protected-in-final
- dev-return-count-rule
- dev-mutable-exception-rule
- dev-final-class-rule
- dev-php84-85-fixture-coverage
- dev-statement-count-rule
- dev-boolean-expression-complexity-rule
- dev-coupling-between-objects-rule
- dev-cyclomatic-complexity-rule-fixes
- dev-cyclomatic-complexity-rule
- dev-remove-qulice-files-from-root
- dev-parameter-number-rule
- dev-too-many-methods-rule
- dev-file-length-rule
- dev-method-length-rule
- dev-method-lines-rule
This package is auto-updated.
Last update: 2026-04-10 08:46:48 UTC
README
Rules
Metrics
| Rule | Default | Description |
|---|---|---|
MethodLengthRule |
100 | Method body must not exceed N lines |
FileLengthRule |
1000 | File must not exceed N lines |
TooManyMethodsRule |
20 | Class must not have more than N methods |
ParameterNumberRule |
3 | Method must not have more than N parameters |
CyclomaticComplexityRule |
10 | Method cyclomatic complexity must not exceed N |
CognitiveComplexityRule |
10 | Method cognitive complexity must not exceed N (nesting is penalised) |
CouplingBetweenObjectsRule |
15 | Class must not depend on more than N unique types |
BooleanExpressionComplexityRule |
3 | Method must not have more than N boolean operators in a single expression |
ClassLengthRule |
500 | Class body must not exceed N lines |
StatementCountRule |
30 | Method must not have more than N executable statements |
Design
| Rule | Description |
|---|---|
FinalClassRule |
All concrete classes must be final |
MutableExceptionRule |
Exception classes must not have non-readonly properties |
ReturnCountRule |
Method must not have more than 1 return statement (default: 1) |
ProtectedMethodInFinalClassRule |
Final classes must not have protected methods |
ProhibitPublicStaticMethodsRule |
Classes must not have public static methods |
ConstructorInitializationRule |
Constructor must only assign $this->property or call parent::__construct() |
Error-prone patterns
| Rule | Description |
|---|---|
NoParameterReassignmentRule |
Method parameters must not be reassigned |
IllegalCatchRule |
Catching Exception, Throwable, RuntimeException, Error is forbidden |
IllegalThrowsRule |
Declaring @throws Exception or other broad types in PHPDoc is forbidden |
InnerAssignmentRule |
Assignment inside conditions (if ($x = foo())) is forbidden |
ModifiedControlVariableRule |
Loop control variable must not be modified inside the loop body |
Naming
| Rule | Default | Description |
|---|---|---|
AbbreviationAsWordInNameRule |
4 | Identifier must not contain more than N consecutive capital letters |
VariableNameRule |
^[a-z][a-zA-Z]{2,19}$ |
Local variable name must match the configured pattern |
PHPDoc style
| Rule | Description |
|---|---|
PhpDocPunctuationClassRule |
PHPDoc summary of every class must end with ., ?, or ! |
PhpDocPunctuationMethodRule |
PHPDoc summary of every method must end with ., ?, or ! |
AtclauseOrderRule |
PHPDoc tags must appear in order: @param → @return → @throws (configurable) |
PhpDocMissingClassRule |
Every named class must have a PHPDoc comment |
PhpDocMissingMethodRule |
Every public method in a class must have a PHPDoc comment (configurable) |
PhpDocMissingPropertyRule |
Every public property in a class must have a PHPDoc comment (configurable) |
ReturnDescriptionCapitalRule |
@return tag description must start with a capital letter |
ParamDescriptionCapitalRule |
@param tag descriptions must start with a capital letter |
NoPhpDocForOverriddenRule |
Overridden methods (#[Override]) must not have a PHPDoc comment |
ClassConstantTypeHintRule |
Every class constant must have a native type declaration (PHP 8.3+) |
NoLineCommentBeforeDeclarationRule |
// and # comments are forbidden before class, method, and property declarations |
NoInlineCommentRule |
Comments inside method bodies are forbidden (suppress directives with @ are allowed) |
Configuration
All configurable rules expose their options as PHPStan parameters under the haspadar namespace. Override any limit in your phpstan.neon without touching service definitions:
parameters: haspadar: methodLength: maxLines: 50 skipBlankLines: true skipComments: true fileLength: maxLines: 500 tooManyMethods: maxMethods: 10 onlyPublic: true parameterNumber: maxParameters: 5 ignoreOverridden: false cyclomaticComplexity: maxComplexity: 5 couplingBetweenObjects: maximum: 10 excludedClasses: - Symfony\Component\HttpFoundation\Request booleanExpressionComplexity: maxOperators: 2 classLength: maxLines: 250 skipBlankLines: true skipComments: true statementCount: maxStatements: 20 returnCount: max: 2 illegalCatch: illegalClassNames: - Exception - Throwable illegalThrows: illegalClassNames: - Error - Throwable ignoreOverriddenMethods: false phpDocPunctuationClass: checkCapitalization: false phpDocPunctuationMethod: checkCapitalization: false atclauseOrder: tagOrder: - '@param' - '@return' - '@throws' phpDocMissingMethod: checkPublicOnly: true skipOverridden: true phpDocMissingProperty: checkPublicOnly: true abbreviation: maxAllowedConsecutiveCapitals: 3 allowedAbbreviations: - JSON - HTTP variableName: pattern: '^[a-z][a-zA-Z]{2,9}$' allowedNames: - id - i - j - db
Default values match the defaults described in the rules table above. Omitting a parameter keeps the default. Diagnostic identifier for AtclauseOrderRule: haspadar.atclauseOrder (for targeted ignores, e.g. @phpstan-ignore haspadar.atclauseOrder).
Installation
composer require --dev haspadar/phpstan-rules
Contributing
Fork the repository, apply changes, and open a pull request.
License
MIT