leonphp13 Jun 2026 18:24

PHP 8.5 lets you mark your own functions, methods, and class constants with the native #[\Deprecated] attribute, not just rely on a docblock tag. I maintain an internal library and I want callers to get a real deprecation notice when they use an old method, so they actually migrate instead of ignoring a comment.

How does this behave at runtime, does it emit a real E_USER_DEPRECATED, and does static analysis pick it up so people see it before runtime? Trying to understand whether this replaces the trigger_error dance I do today.

Replies (5)
dmitry_kv13 Jun 2026 18:54

Yes, calling a symbol marked #[\Deprecated] emits an E_USER_DEPRECATED at runtime automatically, so it replaces the manual trigger_error you put at the top of the method. The attribute takes an optional message and a since argument, so you can say what to use instead and which version deprecated it, and that text shows up in the notice. It is the same error level as before, just declarative and tied to the symbol instead of buried in the body.

0
jnovak13 Jun 2026 20:14

The bigger win is static analysis. PHPStan and the major IDEs understand the attribute and will flag calls to a deprecated symbol at analysis time with a strikethrough or a warning, so your callers see it while writing code, not only when a deprecation notice scrolls past in a log. The docblock @deprecated tag also did this, but having one canonical native attribute that both the runtime and the tools agree on is the point.

0
ivan_morozov13 Jun 2026 21:44

Watch the noise though. If a deprecated method is called in a hot path, you now emit a deprecation notice on every call, which can flood logs the same way a stray trigger_error would. Make sure your error handler dedupes or rate-limits deprecation notices, or your first deploy after annotating a popular old method will bury your logs. The attribute is cleaner but it does not change the volume problem.

0
leonphp13 Jun 2026 23:14

This is exactly what I hoped, the static analysis flag is the part that actually drives migration since people see the strikethrough as they type. I will annotate with both the since and the replacement message so the notice is actionable. Good warning on log volume, our old method is called a lot, so I will make sure the handler dedupes deprecations before I tag it and ship.

0
dmytro_lv14 Jun 2026 00:54

One subtlety: the attribute marks the symbol as deprecated, but if you call the old method from inside your own library, you will trip your own notice too. Audit your internal callers first and route them to the new method before you tag the old one, otherwise you spam yourself. Deprecate from the leaves inward, last so the public entry point is the final thing you mark.

0
Write a reply
Markdown. ```php blocks are runnable.