PHP's built-in attributes, like #[\Override], can only be applied to certain targets. If you put one in the wrong place, PHP stops with an error when it compiles the file, and you can't catch that error or skip it based on the PHP version. This RFC from Daniel Scherzer adds #[\DelayedTargetValidation], which moves those target errors from compile time to runtime.
Why it helps
Say a future PHP version allows #[\Override] on class constants. A library that uses it there would then require that new version, because on older versions the file wouldn't even compile. Library authors would have to wait years before adopting it, even for users already on the newer PHP.
With this attribute, the same code works on both old and new versions. The RFC's example assumes, just for the demo, that #[\Override] gains new targets in PHP 8.6 and 8.7:
class Child extends Base { #[\DelayedTargetValidation] #[\Override] public const NAME = 'Child'; #[\DelayedTargetValidation] #[\Override] public int $id; #[\Override] protected function getName(): string { return parent::getName() . $this->id; } }
On older versions, the misplaced attributes no longer break compilation, and they only raise an error if you instantiate them through reflection. On newer versions, PHP validates them for real.
The RFC itself doesn't change where #[\Override] can go. The idea came from an internals list discussion about allowing #[\Deprecated] in more places.
It only delays errors about where an attribute is placed, without turning off what the attribute does. #[\Override] still complains if a method doesn't actually override anything.
The RFC also considered delaying these checks for every built-in attribute by default, but rejected that idea. Built-in attributes change how PHP runs your code, so a mistake should surface right away.
What it means for existing code
PHP now owns the class name DelayedTargetValidation in the global namespace, and a GitHub search found no one using it. Also, ReflectionAttribute::newInstance() can now throw for built-in attributes, so if your code assumed it never would, you may need to adjust it.
The vote
It passed with 14 votes in favor and 6 against, meeting the two-thirds majority it needed. Voting closed on July 31, 2025, and the page says it's implemented in PHP 8.5.