suhock / phpstan-rules
A set of custom PHPStan rules
Package info
github.com/suhock/phpstan-rules
Type:phpstan-extension
pkg:composer/suhock/phpstan-rules
Requires
- php: ^8.1
- phpstan/phpstan: ^2.2
Requires (Dev)
- ergebnis/phpstan-rules: ^2.0
- friendsofphp/php-cs-fixer: ^3.95
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^10.5 || ^11.5 || ^12.5 || ^13.2
README
A set of custom PHPStan rules.
Installation
composer require --dev suhock/phpstan-rules
If you use phpstan/extension-installer, the rules are registered
automatically. Otherwise include the ruleset in your phpstan.neon:
includes: - vendor/suhock/phpstan-rules/rules.neon
Rules
NoStaticReturnTypeInFinalClassRule
Reports a static return type on a method of a class that cannot be extended: a final class, an enum, or an
anonymous class. In such a class static always resolves to the class itself, so self is equivalent and states the
intent honestly; declaring static advertises late static binding the class does not support, and silently changes the
inferred return type across subclasses if final is ever removed.
final class Example { public function make(): static // reported: use "self" { return new self(); } }
When allowWhenOverriding is enabled (the default), a method whose static return type is inherited from an
overridden parent method or interface is not reported. On PHP 8.4 and earlier a static return type cannot be
narrowed to self in an override without a fatal incompatible-declaration error, so static is the only valid choice
there. Set it to false to flag those overrides as well.
NoPhpstanIgnoreRule
Reports every ignore annotation: @phpstan-ignore, @phpstan-ignore-line, and @phpstan-ignore-next-line. Excludes
those whose error identifiers are all present in a configured allow list. An annotation with no identifier (the
legacy line-based form) can never be allow-listed and is always reported.
// with allowedIdentifiers: ["missingType.iterableValue"] $x = $lib->call(); // @phpstan-ignore missingType.iterableValue <- allowed $y = $lib->call(); // @phpstan-ignore argument.type <- reported (not allow-listed) // @phpstan-ignore-next-line <- reported (no identifier) $z = $lib->call();
This is a hard gate with explicit, curated exceptions, and is disabled by default.
Compared to ergebnis/phpstan-rules' all-or-nothing NoPhpstanIgnoreRule, this one supports an allow list.
To simply ban the line-based
@phpstan-ignore-line/@phpstan-ignore-next-lineforms while allowing the inline@phpstan-ignore <identifier>form, use PHPStan's built-inreportIgnoresWithoutCommentsoption instead — note it also requires an explanatory comment on every ignore.
Configuration
All rules are toggled (and the allow list set) under the parameters.suhock key:
parameters: suhock: noStaticReturnTypeInFinalClass: enabled: true allowWhenOverriding: true # default: skip "static" returns inherited from an override noPhpstanIgnore: enabled: false # default off allowedIdentifiers: - missingType.iterableValue
Development
composer install composer test # PHPUnit composer phpstan # dogfood the rules on this package composer php-cs-fixer # code style