@@ -125,6 +125,66 @@ Stack trace:
125
125
</screen >
126
126
</example >
127
127
</warning >
128
+
129
+ <sect3 xml : id =" language.oop5.basic.class.readonly" >
130
+ <title >Readonly classes</title >
131
+ <para >
132
+ As of PHP 8.2.0, a class can be marked with the
133
+ <literal >readonly</literal > modifier.
134
+ Marking a class as <literal >readonly</literal > will add the
135
+ <literal >readonly</literal > modifier to every declared property,
136
+ and prevent the creation of
137
+ <link linkend =" language.oop5.properties.dynamic-properties" >dynamic properties</link >.
138
+ Moreover, it is impossible to add support for them by using the
139
+ <code >#[AllowDynamicProperties]</code > attribute. Attempting to do so
140
+ will trigger a compile-time error.
141
+ </para >
142
+ <example >
143
+ <programlisting role =" php" >
144
+ <![CDATA[
145
+ <?php
146
+ #[AllowDynamicProperties]
147
+ readonly class Foo {
148
+ }
149
+
150
+ // Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
151
+ ?>
152
+ ]]>
153
+ </programlisting >
154
+ </example >
155
+
156
+ <para >
157
+ As neither untyped, nor static properties can be marked with the
158
+ <literal >readonly</literal > modifier, readonly classes cannot declare
159
+ them either:
160
+ <example >
161
+ <programlisting role =" php" >
162
+ <![CDATA[
163
+ <?php
164
+ readonly class Foo
165
+ {
166
+ public $bar;
167
+ }
168
+
169
+ // Fatal error: Readonly property Foo::$bar must have type
170
+ ?>
171
+ ]]>
172
+ </programlisting >
173
+ <programlisting role =" php" >
174
+ <![CDATA[
175
+ <?php
176
+ readonly class Foo
177
+ {
178
+ public static int $bar;
179
+ }
180
+
181
+ // Fatal error: Readonly class Foo cannot declare static properties
182
+ ?>
183
+ ]]>
184
+ </programlisting >
185
+ </example >
186
+ </para >
187
+ </sect3 >
128
188
</sect2 >
129
189
130
190
<sect2 xml : id =" language.oop5.basic.new" >
0 commit comments