language/oop5/late-static-bindings.xml
009f215fc983eeded6161676bcffdd8cf3b6b080
009f215fc983eeded6161676bcffdd8cf3b6b080
...
...
@@ -3,7 +3,7 @@
3
3
<sect1 xml:id="language.oop5.late-static-bindings" xmlns="http://docbook.org/ns/docbook">
4
4
<title>Late Static Bindings</title>
5
5
<para>
6
-
As of PHP 5.3.0, PHP implements a feature called late static bindings which
6
+
PHP implements a feature called late static bindings which
7
7
can be used to reference the called class in a context of static inheritance.
8
8
</para>
9
9
...
...
@@ -45,22 +45,30 @@
45
45
<programlisting role="php">
46
46
<![CDATA[
47
47
<?php
48
-
class A {
49
-
public static function who() {
48
+
49
+
class A
50
+
{
51
+
public static function who()
52
+
{
50
53
echo __CLASS__;
51
54
}
52
-
public static function test() {
55
+
56
+
public static function test()
57
+
{
53
58
self::who();
54
59
}
55
60
}
56
61
57
-
class B extends A {
58
-
public static function who() {
62
+
class B extends A
63
+
{
64
+
public static function who()
65
+
{
59
66
echo __CLASS__;
60
67
}
61
68
}
62
69
63
70
B::test();
71
+
64
72
?>
65
73
]]>
66
74
</programlisting>
...
...
@@ -80,7 +88,7 @@ A
80
88
<para>
81
89
Late static bindings tries to solve that limitation by introducing a
82
90
keyword that references the class that was initially called at runtime.
83
-
Basically, a keyword that would allow you to reference
91
+
Basically, a keyword that would allow referencing
84
92
<literal>B</literal> from <literal>test()</literal> in the previous
85
93
example. It was decided not to introduce a new keyword but rather use
86
94
<literal>static</literal> that was already reserved.
...
...
@@ -91,22 +99,30 @@ A
91
99
<programlisting role="php">
92
100
<![CDATA[
93
101
<?php
94
-
class A {
95
-
public static function who() {
102
+
103
+
class A
104
+
{
105
+
public static function who()
106
+
{
96
107
echo __CLASS__;
97
108
}
98
-
public static function test() {
109
+
110
+
public static function test()
111
+
{
99
112
static::who(); // Here comes Late Static Bindings
100
113
}
101
114
}
102
115
103
-
class B extends A {
104
-
public static function who() {
116
+
class B extends A
117
+
{
118
+
public static function who()
119
+
{
105
120
echo __CLASS__;
106
121
}
107
122
}
108
123
109
124
B::test();
125
+
110
126
?>
111
127
]]>
112
128
</programlisting>
...
...
@@ -131,43 +147,55 @@ B
131
147
<programlisting role="php">
132
148
<![CDATA[
133
149
<?php
134
-
class A {
135
-
private function foo() {
136
-
echo "success!\n";
150
+
151
+
class A
152
+
{
153
+
private function foo()
154
+
{
155
+
echo "Success!\n";
137
156
}
138
-
public function test() {
157
+
158
+
public function test()
159
+
{
139
160
$this->foo();
140
161
static::foo();
141
162
}
142
163
}
143
164
144
-
class B extends A {
145
-
/* foo() will be copied to B, hence its scope will still be A and
165
+
class B extends A
166
+
{
167
+
/* foo() will be copied to B, hence its scope will still be A and
146
168
* the call be successful */
147
169
}
148
170
149
-
class C extends A {
150
-
private function foo() {
151
-
/* original method is replaced; the scope of the new one is C */
171
+
class C extends A
172
+
{
173
+
private function foo()
174
+
{
175
+
/* Original method is replaced; the scope of the new one is C */
152
176
}
153
177
}
154
178
155
179
$b = new B();
156
180
$b->test();
181
+
157
182
$c = new C();
158
-
$c->test(); //fails
183
+
try {
184
+
$c->test();
185
+
} catch (Error $e) {
186
+
echo $e->getMessage();
187
+
}
188
+
159
189
?>
160
190
]]>
161
191
</programlisting>
162
192
&example.outputs;
163
193
<screen>
164
194
<![CDATA[
165
-
success!
166
-
success!
167
-
success!
168
-
169
-
170
-
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9
195
+
Success!
196
+
Success!
197
+
Success!
198
+
Call to private method C::foo() from scope A
171
199
]]>
172
200
</screen>
173
201
</example>
...
...
@@ -183,34 +211,45 @@ Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php
183
211
<programlisting role="php">
184
212
<![CDATA[
185
213
<?php
186
-
class A {
187
-
public static function foo() {
214
+
215
+
class A
216
+
{
217
+
public static function foo()
218
+
{
188
219
static::who();
189
220
}
190
221
191
-
public static function who() {
192
-
echo __CLASS__."\n";
222
+
public static function who()
223
+
{
224
+
echo __CLASS__ . "\n";
193
225
}
194
226
}
195
227
196
-
class B extends A {
197
-
public static function test() {
228
+
class B extends A
229
+
{
230
+
public static function test()
231
+
{
198
232
A::foo();
199
233
parent::foo();
200
234
self::foo();
201
235
}
202
236
203
-
public static function who() {
204
-
echo __CLASS__."\n";
237
+
public static function who()
238
+
{
239
+
echo __CLASS__ . "\n";
205
240
}
206
241
}
207
-
class C extends B {
208
-
public static function who() {
209
-
echo __CLASS__."\n";
242
+
243
+
class C extends B
244
+
{
245
+
public static function who()
246
+
{
247
+
echo __CLASS__ . "\n";
210
248
}
211
249
}
212
250
213
251
C::test();
252
+
214
253
?>
215
254
]]>
216
255
</programlisting>
217
256