Author: Tim Otten (totten)
Committer: GitHub (web-flow)
Pusher: lacatoire
Date: 2026-09-28T10:20:16+02:00
Commit: https://github.com/php/doc-en/commit/822b0828562580aac0327eb2d84e8e6e06e51a98
Raw diff: https://github.com/php/doc-en/commit/822b0828562580aac0327eb2d84e8e6e06e51a98.diff
Dynamic Properties - Clarify scope of deprecation (#2181)
* Dynamic Properties - Clarify scope of deprecation
The phrasing in the manual is confusing/misleading -- it suggests that all
forms of dynamism are deprecated. But let's go to the RFC that introduced
the current policy:
https://wiki.php.net/rfc/deprecate_dynamic_properties
"This RFC proposes to deprecate and later remove the creation of dynamic
properties, unless the class explicitly allows dynamic properties."
The sentence structure is awkward but clear -- it allows for *explicitly*
enabled dynamic-properties. This interpretation aligns with the actual
behavior that was implemented. Compare:
1. At the time of the RFC's writing, there was implicit/universal support
for dynamic-properties. PHP 8.2 respects the mechanism but generates
a deprecation warning.
2. As a replacement, the RFC added a new explicit/opt-in mechanism for
dynamic-properties (AllowDynamicProperties). PHP 8.2 was the first
version to have this. It does not produce any deprecation warnings.
* Update allowdynamicproperties.xml and properties.xml
Co-authored-by: Kamil Tekiela <tekiela246@gmail.com>
* properties.xml - Split the affirmative and cautionary notes
There is a sense in which "dynamic properties" are supported - as long as
you use them in the defined way (eg stdClass, AllowDynamicProperties).
There is another sense in which "dynamic properties" are not supported -
when you use them in an old/bad way.
After re-reading, it seemed weird that the affirmative parts were listed
inside the cautionary parts. Seems easier to read as separate statements.
* allowdynamicproperties.xml - Remove crystal ball
* Use simpara for inline-only paragraphs (Style Check)
* Add missing <title> to formal <example> blocks
DocBook example requires a title; jing rejected the build with
'simpara not allowed yet; expected info, title or titleabbrev'.
* Address kamil-tekiela's review nits
Fix oxymoronic example title, drop redundant parenthetical, and use
consistent 'dynamic property' terminology.
---------
Co-authored-by: Kamil Tekiela <tekiela246@gmail.com>
Co-authored-by: Louis-Arnaud <la.catoire@gmail.com>
Changed paths:
M language/oop5/properties.xml
M language/predefined/attributes/allowdynamicproperties.xml
Diff:
diff --git a/language/oop5/properties.xml b/language/oop5/properties.xml
index a3e7f23a00ae..d7e11e6b0f7f 100644
--- a/language/oop5/properties.xml
+++ b/language/oop5/properties.xml
@@ -408,16 +408,20 @@ var_dump($test2->prop); // NULL
This dynamically created property will <emphasis>only</emphasis> be
available on this class instance.
</para>
-
+ <simpara>
+ Dynamic properties are supported by <link
linkend="stdclass.intro">stdClass</link> and its subclasses. Other classes may
enable similar behavior with <link
linkend="allowdynamicproperties.intro">AllowDynamicProperties</link> or <link
linkend="language.oop5.overloading">property overloading</link>.
+ </simpara>
<warning>
<simpara>
- Dynamic properties are deprecated as of PHP 8.2.0.
+ Creating a dynamic property is deprecated as of PHP 8.2.0,
+ unless the class is marked with the
+ <code>#[\AllowDynamicProperties]</code> attribute.
It is recommended to declare the property instead.
To handle arbitrary property names, the class should implement the magic
methods <link linkend="object.get">__get()</link> and
<link linkend="object.set">__set()</link>.
- As a last resort the class can be marked with the
- <code>#[\AllowDynamicProperties]</code> attribute.
+ Marking the class with the attribute remains an option, but is
+ generally considered a last resort.
</simpara>
</warning>
</sect2>
diff --git a/language/predefined/attributes/allowdynamicproperties.xml
b/language/predefined/attributes/allowdynamicproperties.xml
index f3410a5e7ea6..bca19cc3b849 100644
--- a/language/predefined/attributes/allowdynamicproperties.xml
+++ b/language/predefined/attributes/allowdynamicproperties.xml
@@ -20,6 +20,15 @@
attribute.
</simpara>
</note>
+ <note>
+ <simpara>
+ This attribute was introduced in PHP 8.2.0 as the explicit way to allow
+ dynamic properties. Creating a dynamic property on a class that does
+ not use this attribute, and that does not implement
+ <link linkend="object.get">__get()</link> or
+ <link linkend="object.set">__set()</link>, is deprecated.
+ </simpara>
+ </note>
</section>
<section xml:id="allowdynamicproperties.synopsis">
@@ -40,33 +49,46 @@
<section>
&reftitle.examples;
- <simpara>
- Dynamic properties are deprecated as of PHP 8.2.0,
- thus using them without marking the class with this attribute will emit
- a deprecation notice.
- </simpara>
<example>
- <title>AllowDynamicProperties with non-existing property</title>
+ <title>AllowDynamicProperties with a dynamic property</title>
+ <simpara>
+ To enable dynamic properties, add <literal>#[\AllowDynamicProperties]</literal>.
+ </simpara>
<programlisting role="php">
<![CDATA[
<?php
-class DefaultBehaviour { }
-
#[\AllowDynamicProperties]
-class ClassAllowsDynamicProperties { }
+class ValidExample { }
-$o1 = new DefaultBehaviour();
-$o2 = new ClassAllowsDynamicProperties();
+$obj = new ValidExample();
+$obj->myDynamicProp = 1234;
+?>
+]]>
+ </programlisting>
+ </example>
-$o1->nonExistingProp = true;
-$o2->nonExistingProp = true;
+ <example>
+ <title>AllowDynamicProperties with non-existing property</title>
+ <simpara>
+ As of PHP 8.2.0, the declaration is required unless the class uses
+ this attribute. Creating an undeclared property
+ on such a class emits a deprecation notice.
+ </simpara>
+
+ <programlisting role="php">
+<![CDATA[
+<?php
+class InvalidExample { }
+
+$obj = new InvalidExample();
+$obj->myUnknownProperty = 1234;
?>
]]>
</programlisting>
&example.outputs.82;
<screen>
<![CDATA[
-Deprecated: Creation of dynamic property DefaultBehaviour::$nonExistingProp is deprecated in file
on line 10
+Deprecated: Creation of dynamic property InvalidExample::$myUnknownProperty is deprecated in file
on line 5
]]>
</screen>
</example>