jiripudil/phpstan-sealed-classes
PHPStan extension to enforce “sealed” classes in PHP: declare which classes may extend a base class and report violations during static analysis. Helps keep inheritance under control, prevent accidental subclassing, and maintain clear, stable APIs.
Install via Composer: composer require --dev jiripudil/phpstan-sealed-classes. Then enable it in your PHPStan config (phpstan.neon):
includes:
- vendor/jiripudil/phpstan-sealed-classes/extension.neon
Start by annotating your sealed classes/interfaces with @phpstan-sealed and listing permitted subclasses (e.g., @phpstan-sealed-with class Foo, class Bar). The first use case is preventing accidental subclassing outside the allowed set — ideal for enum-like type hierarchies (e.g., algebraic data types in domain models).
Use @phpstan-sealed-with on sealed interfaces or abstract classes to enforce compile-time subclass constraints. Typical pattern:
/**
* @phpstan-sealed-with Operation\Add, Operation\Subtract
*/
interface Operation {}
final class Add implements Operation {}
final class Subtract implements Operation {}
Works best with PSR-4 autoloading — ensure permitted classes are autoloadable. Combine with @extends for genericsealed types (e.g., sealed Result<Ok, Error>). Leverage IDE auto-imports: PHPStan will surface only allowed subclasses in @phpstan-sealed-with, reducing cognitive load during maintenance.
@phpstan-sealed-with isn’t autoloadable (e.g., misnamed file), PHPStan may silently skip validation — always run composer dump-autoload after adding classes.@phpstan-sealed-with are case-sensitive and must match the exact FQCN (including namespace), even if PHP allows case-insensitive class resolution.final children require each child to be explicitly listed — don’t assume PHP’s inheritance graph is inferred.final children of sealed types). Use phpstan-phpdoc-parser to extend the docblock parser if you need custom annotations.phpstan analyse -l max and watch for "Sealed type..." errors — they often reveal missing final keywords or incorrect namespaces.How can I help you explore Laravel packages today?