-
Notifications
You must be signed in to change notification settings - Fork 788
/
Copy pathanonymous.xml
223 lines (198 loc) · 4.44 KB
/
anonymous.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<sect1 xml:id="language.oop5.anonymous" xmlns="http://docbook.org/ns/docbook">
<title>Anonymous classes</title>
<para>
Anonymous classes are useful when simple, one-off objects need to be created.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// Using an explicit class
class Logger
{
public function log($msg)
{
echo $msg;
}
}
$util->setLogger(new Logger());
// Using an anonymous class
$util->setLogger(new class {
public function log($msg)
{
echo $msg;
}
});
]]>
</programlisting>
</informalexample>
<para>
They can pass arguments through to their constructors, extend other classes,
implement interfaces, and use traits just like a normal class can:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class SomeClass {}
interface SomeInterface {}
trait SomeTrait {}
var_dump(new class(10) extends SomeClass implements SomeInterface {
private $num;
public function __construct($num)
{
$this->num = $num;
}
use SomeTrait;
});
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(class@anonymous)#1 (1) {
["Command line code0x104c5b612":"class@anonymous":private]=>
int(10)
}
]]>
</screen>
</informalexample>
<para>
Nesting an anonymous class within another class does not give it access to
any private or protected methods or properties of that outer class. In order
to use the outer class' protected properties or methods, the anonymous class
can extend the outer class. To use the private properties of
the outer class in the anonymous class, they must be passed through its
constructor:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class Outer
{
private $prop = 1;
protected $prop2 = 2;
protected function func1()
{
return 3;
}
public function func2()
{
return new class($this->prop) extends Outer {
private $prop3;
public function __construct($prop)
{
$this->prop3 = $prop;
}
public function func3()
{
return $this->prop2 + $this->prop3 + $this->func1();
}
};
}
}
echo (new Outer)->func2()->func3();
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
6
]]>
</screen>
</informalexample>
<para>
All objects created by the same anonymous class declaration are instances of
that very class.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function anonymous_class()
{
return new class {};
}
if (get_class(anonymous_class()) === get_class(anonymous_class())) {
echo 'same class';
} else {
echo 'different class';
}]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
same class
]]>
</screen>
</informalexample>
<note>
<para>
Note that anonymous classes are assigned a name by the engine, as
demonstrated in the following example. This name has to be regarded an
implementation detail, which should not be relied upon.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo get_class(new class {});
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
class@anonymous/in/oNi1A0x7f8636ad2021
]]>
</screen>
</informalexample>
</note>
<sect2 xml:id="language.oop5.anonymous.readonly">
<title>Readonly anonymous classes</title>
<simpara>
As of PHP 8.3.0, the <literal>readonly</literal> modifier can
be applied to anonymous classes.
</simpara>
<example xml:id="language.oop5.anonymous.readonly.example">
<title>Defining a readonly anonymous class</title>
<programlisting role="php">
<![CDATA[
<?php
// Using an anonymous class
var_dump(new readonly class('[DEBUG]') {
public function __construct(private string $prefix)
{
}
public function log($msg)
{
echo $this->prefix . ' ' . $msg;
}
});
]]>
</programlisting>
</example>
</sect2>
</sect1>
<!-- 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
-->