[DOC-CVS] [doc-en] master: DelayedTargetValidation: Document attribute (PHP 8.5) (#5457)

[email protected] (Jordi Kroon via GitHub) Thu, 21 May 2026 18:37:54 +0000
Newsgroups php.doc.cvs
Message-ID <[email protected]>
Author: Jordi Kroon (jordikroon)
Committer: GitHub (web-flow)
Pusher: jordikroon
Date: 2026-05-21T20:37:51+02:00

Commit: https://github.com/php/doc-en/commit/efda0bb311990257715bd3a41ab2b04769ce2e4e
Raw diff: https://github.com/php/doc-en/commit/efda0bb311990257715bd3a41ab2b04769ce2e4e.diff

DelayedTargetValidation: Document attribute (PHP 8.5) (#5457)

* add DelayedTargetValidation attribute documentation

Co-authored-by: Louis-Arnaud <[email protected]>

Changed paths:
  A  language/predefined/attributes/delayedtargetvalidation.xml
  M  language/predefined/attributes.xml
  M  language/predefined/versions.xml


Diff:

diff --git a/language/predefined/attributes.xml b/language/predefined/attributes.xml
index 3e97de7913c9..c8da10e32d2e 100644
--- a/language/predefined/attributes.xml
+++ b/language/predefined/attributes.xml
@@ -3,13 +3,14 @@
  <title>Predefined Attributes</title>
 
  <partintro>
-  <para>
+  <simpara>
    PHP provides some predefined attributes that can be used.
-  </para>
+  </simpara>
  </partintro>
 
  &language.predefined.attributes.attribute;
  &language.predefined.attributes.allowdynamicproperties;
+ &language.predefined.attributes.delayedtargetvalidation;
  &language.predefined.attributes.deprecated;
  &language.predefined.attributes.nodiscard;
  &language.predefined.attributes.override;
diff --git a/language/predefined/attributes/delayedtargetvalidation.xml b/language/predefined/attributes/delayedtargetvalidation.xml
new file mode 100644
index 000000000000..8f291b2cb258
--- /dev/null
+++ b/language/predefined/attributes/delayedtargetvalidation.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<reference xml:id="class.delayedtargetvalidation" role="class" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>The DelayedTargetValidation attribute</title>
+ <titleabbrev>DelayedTargetValidation</titleabbrev>
+
+ <partintro>
+
+  <section xml:id="delayedtargetvalidation.intro">
+   &reftitle.intro;
+   <simpara>
+    This attribute delays target validation errors for internal attributes
+    from compile time to when the attribute is instantiated via the Reflection API.
+   </simpara>
+   <simpara>
+    When applied to a declaration, any invalid usage of internal attributes
+    on the same target will not trigger a compile time error. Instead, the
+    validation is deferred and performed when the attribute is instantiated
+    via <link linkend="reflectionattribute.newinstance">ReflectionAttribute::newInstance()</link>.
+   </simpara>
+   <simpara>
+    This is primarily intended for forward compatibility, allowing code to
+    use attributes that may gain additional valid targets in future PHP
+    versions without breaking on older versions.
+   </simpara>
+  </section>
+
+  <section xml:id="delayedtargetvalidation.synopsis">
+   &reftitle.classsynopsis;
+
+   <classsynopsis class="class">
+    <ooclass>
+     <modifier role="attribute">#[\Attribute]</modifier>
+     <modifier>final</modifier>
+     <classname>DelayedTargetValidation</classname>
+    </ooclass>
+   </classsynopsis>
+
+  </section>
+
+  <section xml:id="delayedtargetvalidation.examples">
+   &reftitle.examples;
+
+   <example>
+    <title>Delaying validation of an invalid target</title>
+    <programlisting role="php"><![CDATA[
+<?php
+
+class Base {
+    protected function foo(): void {}
+}
+
+class Child extends Base {
+
+    #[\DelayedTargetValidation]
+    #[\Override]
+    public const NAME = 'child';
+
+    #[\Override]
+    protected function foo(): void {}
+}
+]]></programlisting>
+
+    <simpara>
+     On PHP versions where <classname>Override</classname> is not allowed on
+     class constants, this does not produce a compile time error.
+    </simpara>
+   </example>
+
+   <example>
+    <title>Validation occurs during reflection</title>
+    <programlisting role="php"><![CDATA[
+<?php
+
+$reflection = new ReflectionClassConstant(Child::class, 'NAME');
+
+foreach ($reflection->getAttributes() as $attribute) {
+    $attribute->newInstance(); // May throw if invalid
+}
+]]></programlisting>
+
+    <simpara>
+     When any attribute applied to the same target (other than
+     DelayedTargetValidation itself) is instantiated via reflection using
+     <link linkend="reflectionattribute.newinstance">ReflectionAttribute::newInstance()</link>,
+     target validation is performed and an exception may be thrown if the attribute
+     is used on an unsupported target.
+    </simpara>
+   </example>
+
+  </section>
+
+  <section xml:id="delayedtargetvalidation.notes">
+   &reftitle.notes;
+   <simpara>
+    This attribute only affects target validation of internal attributes.
+   </simpara>
+   <simpara>
+    It does not suppress functional validation performed by those attributes.
+    For example, <classname>Override</classname> will still emit an error if a
+    method does not actually override a parent method.
+   </simpara>
+  </section>
+
+  <section xml:id="delayedtargetvalidation.seealso">
+   &reftitle.seealso;
+   <simplelist>
+    <member><link linkend="language.attributes">Attributes overview</link></member>
+    <member><link linkend="class.override">Override</link></member>
+   </simplelist>
+  </section>
+
+ </partintro>
+
+</reference>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+indent-tabs-mode:nil
+sgml-parent-document:nil
+sgml-default-dtd-file:"~/.phpdoc/manual.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+vim600: syn=xml fen fdm=syntax fdl=2 si
+vim: et tw=78 syn=sgml
+vi: ts=1 sw=1
+-->
diff --git a/language/predefined/versions.xml b/language/predefined/versions.xml
index 65b26579cf0e..754395191216 100644
--- a/language/predefined/versions.xml
+++ b/language/predefined/versions.xml
@@ -181,6 +181,7 @@
  <function name="Override::__construct" from="PHP 8 &gt;= 8.3.0"/>
  <function name="Deprecated" from="PHP 8 &gt;= 8.4.0"/>
  <function name="Deprecated::__construct" from="PHP 8 &gt;= 8.4.0"/>
+ <function name="DelayedTargetValidation" from="PHP 8 &gt;= 8.5.0"/>
  <function name="NoDiscard" from="PHP 8 &gt;= 8.5.0"/>
  <function name="NoDiscard::__construct" from="PHP 8 &gt;= 8.5.0"/>
  <function name="__PHP_Incomplete_Class" from="PHP 4 &gt;=4.0.1, PHP 5, PHP 7, PHP 8"/>