Menu

Restricted Usage Extensions—You Don’t Always Need a Custom Rule

April 27, 2025 · 2 min read

Recently I’ve wanted to implement support for the @internal PHPDoc tag. The good news was there was already a similar set of rules in phpstan-deprecation-rules for the @deprecated tag. The bad news was the logic around @deprecated was hardcoded there, meaning I’d have to copy and adjust all the rules.

I thought there should be a better way because this is a very common use-case and not everyone should be forced to reinvent the same wheel. If people have a need for rules around attributes like #[NamespaceVisibility] or #[Friend], it should not be their job to figure out all the rules needed for a comprehensive coverage of these restrictions.

Take methods for example: Everyone would implement a rule for a traditional method call like $foo->doBar(1, 2, 3), but only a few would remember that first-class callables like $foo->doBar(...) should be covered as well.

Or class names. The new extension currently covers 26 locations where a class name can occur in PHP code or PHPDocs. The great advantage of the extension interface is that it’s future-proof and we can call it as new places with class names appear in the PHP language or as we add new PHPDoc features.

Besides taking advantage of the new extensions to implement the @internal tag rules, I went back to phpstan-deprecation-rules and refactored it with these new capabilities. It fixed small inconsistencies like missing class name check for static property fetch, wrong class names in some error messages, or reported line numbers in multi-line function signatures. With bleeding edge enabled, it will report deprecated class names in more places.

The Restricted Usage Extensions were released in PHPStan 2.1.13. Head over to the developer guide to learn how to use them!


Do you like PHPStan and use it every day? Consider supporting further development of PHPStan. I’d really appreciate it!

Theme
A
© 2025 PHPStan s.r.o.