language/oop5/properties.xml
c1f37a6c270aadbbb3da56a3973ffd62197adf2b
c1f37a6c270aadbbb3da56a3973ffd62197adf2b
...
...
@@ -7,34 +7,33 @@
7
7
Class member variables are called <emphasis>properties</emphasis>.
8
8
They may be referred to using other terms such as <emphasis>fields</emphasis>,
9
9
but for the purposes of this reference <emphasis>properties</emphasis>
10
-
will be used. They are defined by using one of the keywords
11
-
<literal>public</literal>, <literal>protected</literal>, or
12
-
<literal>private</literal>, optionally, as of PHP 7.4,
10
+
will be used. They are defined by using at least one modifier (such as
11
+
<xref linkend="language.oop5.visibility"/>,
12
+
<xref linkend="language.oop5.static"/>,
13
+
or, as of PHP 8.1.0, <link linkend="language.oop5.properties.readonly-properties">readonly</link>),
14
+
optionally (except for <code>readonly</code> properties), as of PHP 7.4,
13
15
followed by a type declaration, followed by a normal variable declaration.
14
16
This declaration may include an initialization, but this initialization
15
17
must be a <link linkend="language.constants">constant</link> value.
16
18
</para>
17
-
<para>
18
-
See <xref linkend="language.oop5.visibility" /> for more
19
-
information on the meanings
20
-
of <literal>public</literal>, <literal>protected</literal>,
21
-
and <literal>private</literal>.
22
-
</para>
23
19
<note>
24
20
<para>
25
-
An alternative and not recommended way of declaring class properties, as it is to maintain backward
26
-
compatibility with PHP 4, is by using
27
-
the <literal>var</literal> keyword.
28
-
It will treat the property identically as it would have been
29
-
declared as <literal>public</literal>.
21
+
An obsolete way of declaring class properties, is by using the
22
+
<literal>var</literal> keyword instead of a modifier.
30
23
</para>
31
24
</note>
25
+
<note>
26
+
<simpara>
27
+
A property declared without a <xref linkend="language.oop5.visibility"/>
28
+
modifier will be declared as <literal>public</literal>.
29
+
</simpara>
30
+
</note>
32
31
<para>
33
32
Within class methods non-static properties may be accessed by using
34
33
<literal>-></literal> (Object Operator): <varname>$this->property</varname>
35
34
(where <literal>property</literal> is the name of the property).
36
35
Static properties are accessed by using the <literal>::</literal> (Double Colon):
37
-
<varname>self::$property</varname>. See <link linkend="language.oop5.static">Static Keyword</link>
36
+
<varname>self::$property</varname>. See <xref linkend="language.oop5.static" />
38
37
for more information on the difference between static and non-static properties.
39
38
</para>
40
39
<para>
...
...
@@ -46,7 +45,7 @@
46
45
<para>
47
46
<example>
48
47
<title>Property declarations</title>
49
-
<programlisting role="php">
48
+
<programlisting role="php" annotations="non-interactive">
50
49
<![CDATA[
51
50
<?php
52
51
class SimpleClass
...
...
@@ -67,6 +66,10 @@ EOD;
67
66
public $var8 = <<<'EOD'
68
67
hello world
69
68
EOD;
69
+
70
+
// Without visibility modifier:
71
+
static $var9;
72
+
readonly int $var10;
70
73
}
71
74
?>
72
75
]]>
...
...
@@ -85,7 +88,7 @@ EOD;
85
88
<sect2 xml:id="language.oop5.properties.typed-properties">
86
89
<title>Type declarations</title>
87
90
<para>
88
-
As of PHP 7.4.0, property definitions can include a
91
+
As of PHP 7.4.0, property definitions can include
89
92
<xref linkend="language.types.declarations" />,
90
93
with the exception of <type>callable</type>.
91
94
<example>
...
...
@@ -189,10 +192,16 @@ Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be ac
189
192
<sect2 xml:id="language.oop5.properties.readonly-properties">
190
193
<title>Readonly properties</title>
191
194
<para>
192
-
As of PHP 8.1.0, a property can be declared with the <code>readonly</code> modifier, which prevents modification of the property after initialization.
195
+
As of PHP 8.1.0, a property can be declared with the <literal>readonly</literal> modifier,
196
+
which prevents modification of the property after initialization. Prior to PHP 8.4.0
197
+
a <literal>readonly</literal> property is implicitly private-set, and may only be written to
198
+
from the same class. As of PHP 8.4.0, <literal>readonly</literal> properties are implicitly
199
+
<link linkend="language.oop5.visibility-members-aviz"><literal>protected(set)</literal></link>,
200
+
so may be set from child classes. That may be overridden
201
+
explicitly if desired.
193
202
<example>
194
203
<title>Example of readonly properties</title>
195
-
<programlisting role="php">
204
+
<programlisting role="php" annotations="non-interactive">
196
205
<![CDATA[
197
206
<?php
198
207
...
...
@@ -219,7 +228,7 @@ $test->prop = "foobar";
219
228
<note>
220
229
<para>
221
230
The readonly modifier can only be applied to <link linkend="language.oop5.properties.typed-properties">typed properties</link>.
222
-
A readonly property without type constraints can be created using the <xref linkend="language.types.declarations.mixed" /> type.
231
+
A readonly property without type constraints can be created using the <xref linkend="language.types.mixed"/> type.
223
232
</para>
224
233
</note>
225
234
<note>
...
...
@@ -232,7 +241,7 @@ $test->prop = "foobar";
232
241
A readonly property can only be initialized once, and only from the scope where it has been declared. Any other assignment or modification of the property will result in an <classname>Error</classname> exception.
233
242
<example>
234
243
<title>Illegal initialization of readonly properties</title>
235
-
<programlisting role="php">
244
+
<programlisting role="php" annotations="non-interactive">
236
245
<![CDATA[
237
246
<?php
238
247
class Test1 {
...
...
@@ -251,8 +260,8 @@ $test1->prop = "foobar";
251
260
<note>
252
261
<para>
253
262
Specifying an explicit default value on readonly properties is not allowed, because a readonly property with a default value is essentially the same as a constant, and thus not particularly useful.
254
-
<example>
255
-
<programlisting role="php">
263
+
<informalexample>
264
+
<programlisting role="php" annotations="non-interactive">
256
265
<![CDATA[
257
266
<?php
258
267
...
...
@@ -263,7 +272,7 @@ class Test {
263
272
?>
264
273
]]>
265
274
</programlisting>
266
-
</example>
275
+
</informalexample>
267
276
</para>
268
277
</note>
269
278
<note>
...
...
@@ -273,8 +282,8 @@ class Test {
273
282
</note>
274
283
<para>
275
284
Modifications are not necessarily plain assignments, all of the following will also result in an <classname>Error</classname> exception:
276
-
<example>
277
-
<programlisting role="php">
285
+
<informalexample>
286
+
<programlisting role="php" annotations="non-interactive">
278
287
<![CDATA[
279
288
<?php
280
289
...
...
@@ -298,12 +307,12 @@ foreach ($test as &$prop);
298
307
?>
299
308
]]>
300
309
</programlisting>
301
-
</example>
310
+
</informalexample>
302
311
</para>
303
312
<para>
304
313
However, readonly properties do not preclude interior mutability. Objects (or resources) stored in readonly properties may still be modified internally:
305
-
<example>
306
-
<programlisting role="php">
314
+
<informalexample>
315
+
<programlisting role="php" annotations="non-interactive">
307
316
<![CDATA[
308
317
<?php
309
318
...
...
@@ -317,12 +326,64 @@ $test->obj->foo = 1;
317
326
// Illegal reassignment.
318
327
$test->obj = new stdClass;
319
328
?>
329
+
]]>
330
+
</programlisting>
331
+
</informalexample>
332
+
</para>
333
+
<para>
334
+
As of PHP 8.3.0, readonly properties can be reinitialized when cloning an object
335
+
using the <link linkend="object.clone">__clone()</link> method.
336
+
<example>
337
+
<title>Readonly properties and cloning</title>
338
+
<programlisting role="php">
339
+
<![CDATA[
340
+
<?php
341
+
class Test1 {
342
+
public readonly ?string $prop;
343
+
344
+
public function __clone() {
345
+
$this->prop = null;
346
+
}
347
+
348
+
public function setProp(string $prop): void {
349
+
$this->prop = $prop;
350
+
}
351
+
}
352
+
353
+
$test1 = new Test1;
354
+
$test1->setProp('foobar');
355
+
356
+
$test2 = clone $test1;
357
+
var_dump($test2->prop); // NULL
358
+
?>
320
359
]]>
321
360
</programlisting>
322
361
</example>
323
362
</para>
324
363
</sect2>
325
364
365
+
<sect2 xml:id="language.oop5.properties.dynamic-properties">
366
+
<title>Dynamic properties</title>
367
+
<para>
368
+
If trying to assign to a non-existent property on an &object;,
369
+
PHP will automatically create a corresponding property.
370
+
This dynamically created property will <emphasis>only</emphasis> be
371
+
available on this class instance.
372
+
</para>
373
+
374
+
<warning>
375
+
<simpara>
376
+
Dynamic properties are deprecated as of PHP 8.2.0.
377
+
It is recommended to declare the property instead.
378
+
To handle arbitrary property names, the class should implement the magic
379
+
methods <link linkend="object.get">__get()</link> and
380
+
<link linkend="object.set">__set()</link>.
381
+
At last resort the class can be marked with the
382
+
<code>#[\AllowDynamicProperties]</code> attribute.
383
+
</simpara>
384
+
</warning>
385
+
</sect2>
386
+
326
387
</sect1>
327
388
<!-- Keep this comment at the end of the file
328
389
Local variables:
329
390