{"id":16292304,"url":"https://github.com/jiripudil/phpstan-sealed-classes","last_synced_at":"2025-10-23T20:02:47.859Z","repository":{"id":62550990,"uuid":"505141994","full_name":"jiripudil/phpstan-sealed-classes","owner":"jiripudil","description":"PHPStan extension for sealed classes and interfaces.","archived":false,"fork":false,"pushed_at":"2024-11-11T09:08:46.000Z","size":38,"stargazers_count":33,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-31T09:04:26.735Z","etag":null,"topics":["hacktoberfest","php","phpstan","phpstan-extension","sealed-class","sealed-interface"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jiripudil.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"jiripudil"}},"created_at":"2022-06-19T15:05:06.000Z","updated_at":"2024-12-07T06:46:43.000Z","dependencies_parsed_at":"2025-01-31T09:10:57.211Z","dependency_job_id":"842c6496-7d0e-4367-a756-fad65d1d2563","html_url":"https://github.com/jiripudil/phpstan-sealed-classes","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiripudil%2Fphpstan-sealed-classes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiripudil%2Fphpstan-sealed-classes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiripudil%2Fphpstan-sealed-classes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jiripudil%2Fphpstan-sealed-classes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jiripudil","download_url":"https://codeload.github.com/jiripudil/phpstan-sealed-classes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247634319,"owners_count":20970510,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","php","phpstan","phpstan-extension","sealed-class","sealed-interface"],"created_at":"2024-10-10T20:05:28.691Z","updated_at":"2025-10-23T20:02:47.854Z","avatar_url":"https://github.com/jiripudil.png","language":"PHP","funding_links":["https://github.com/sponsors/jiripudil"],"categories":[],"sub_categories":[],"readme":"\u003e [!IMPORTANT]\n\u003e This package is obsolete. You can now use the built-in [`@phpstan-sealed` annotation](https://phpstan.org/writing-php-code/phpdocs-basics#sealed-classes) introduced in PHPStan 2.1.18.\n\n# Sealed classes with PHPStan\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/jiripudil/phpstan-sealed-classes/test.yml?branch=main)](https://github.com/jiripudil/phpstan-sealed-classes/actions?query=workflow%3ATest)\n[![latest version](https://img.shields.io/packagist/v/jiripudil/phpstan-sealed-classes)](https://packagist.org/packages/jiripudil/phpstan-sealed-classes)\n[![license](https://img.shields.io/packagist/l/jiripudil/phpstan-sealed-classes)](https://packagist.org/packages/jiripudil/phpstan-sealed-classes)\n[![monthly downloads](https://img.shields.io/packagist/dm/jiripudil/phpstan-sealed-classes)](https://packagist.org/packages/jiripudil/phpstan-sealed-classes)\n[![downloads total](https://img.shields.io/packagist/dt/jiripudil/phpstan-sealed-classes)](https://packagist.org/packages/jiripudil/phpstan-sealed-classes)\n\nThis extension adds support for sealed classes and interfaces to PHPStan.\n\n## Installation\n\nTo use this extension, require it via Composer\n\n```shell\ncomposer require --dev jiripudil/phpstan-sealed-classes\n```\n\nIf you are using [`phpstan/extension-installer`](https://github.com/phpstan/extension-installer), this extension's configuration will be automatically enabled.\n\nOtherwise, you need to include it explicitly in your `phpstan.neon`:\n\n```neon\nincludes:\n    - vendor/jiripudil/phpstan-sealed-classes/extension.neon\n```\n\n\n## Usage\n\nSealed classes and interfaces allow developers to restrict class hierarchies: a sealed class can only be subclassed by classes that are explicitly permitted to do so. The same applies to sealed interfaces and their implementations. In a way, sealed classes are similar to enumerations, with an important distinction: while enums are singletons, a subclass of a sealed class can have _multiple_ instances, each with its own state.\n\nYou can seal a class or an interface by attributing it as `#[Sealed]`. The attribute accepts a list of permitted descendants or implementations:\n\n```php\n\u003c?php\n\nuse JiriPudil\\SealedClasses\\Sealed;\n\n#[Sealed(permits: [AllowedImplementation::class, AnotherImplementation::class])]\ninterface SealedInterface {}\n\nclass AllowedImplementation implements SealedInterface {}\nclass AnotherImplementation implements SealedInterface {}\nclass DisallowedImplementation implements SealedInterface {}\n```\n\nWhile the first two classes will be allowed, PHPStan will report an error for the third:\n\n```\n------ ----------------------------------------------------------------------------------\n Line   sealed-interface.php\n------ ----------------------------------------------------------------------------------\n 10     Type DisallowedImplementation is not allowed to be a subtype of SealedInterface.\n------ ----------------------------------------------------------------------------------\n```\n\nNote that the restrictions do not apply to indirect subclasses. If a direct subclass of a sealed class is not sealed itself, it can be further extended without raising any errors. This code is perfectly fine:\n\n```php\n\u003c?php\n\nuse JiriPudil\\SealedClasses\\Sealed;\n\n#[Sealed(permits: [AllowedDescendant::class])]\nabstract class SealedClass {}\n\nclass AllowedDescendant extends SealedClass {}\nclass IndirectDescendant extends AllowedDescendant {}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjiripudil%2Fphpstan-sealed-classes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjiripudil%2Fphpstan-sealed-classes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjiripudil%2Fphpstan-sealed-classes/lists"}