1 | <HTML
|
---|
2 | ><HEAD
|
---|
3 | ><TITLE
|
---|
4 | >References inside the constructor</TITLE
|
---|
5 | ><META
|
---|
6 | NAME="GENERATOR"
|
---|
7 | CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
|
---|
8 | REL="HOME"
|
---|
9 | TITLE="Manuál PHP"
|
---|
10 | HREF="index.html"><LINK
|
---|
11 | REL="UP"
|
---|
12 | TITLE="Classes and Objects"
|
---|
13 | HREF="language.oop.html"><LINK
|
---|
14 | REL="PREVIOUS"
|
---|
15 | TITLE="The magic functions __sleep and __wakeup"
|
---|
16 | HREF="language.oop.magic-functions.html"><LINK
|
---|
17 | REL="NEXT"
|
---|
18 | TITLE="Vysvìtlení referencí (odkazù)"
|
---|
19 | HREF="language.references.html"><META
|
---|
20 | HTTP-EQUIV="Content-type"
|
---|
21 | CONTENT="text/html; charset=ISO-8859-2"></HEAD
|
---|
22 | ><BODY
|
---|
23 | CLASS="sect1"
|
---|
24 | BGCOLOR="#FFFFFF"
|
---|
25 | TEXT="#000000"
|
---|
26 | LINK="#0000FF"
|
---|
27 | VLINK="#840084"
|
---|
28 | ALINK="#0000FF"
|
---|
29 | ><DIV
|
---|
30 | CLASS="NAVHEADER"
|
---|
31 | ><TABLE
|
---|
32 | SUMMARY="Header navigation table"
|
---|
33 | WIDTH="100%"
|
---|
34 | BORDER="0"
|
---|
35 | CELLPADDING="0"
|
---|
36 | CELLSPACING="0"
|
---|
37 | ><TR
|
---|
38 | ><TH
|
---|
39 | COLSPAN="3"
|
---|
40 | ALIGN="center"
|
---|
41 | >Manuál PHP</TH
|
---|
42 | ></TR
|
---|
43 | ><TR
|
---|
44 | ><TD
|
---|
45 | WIDTH="10%"
|
---|
46 | ALIGN="left"
|
---|
47 | VALIGN="bottom"
|
---|
48 | ><A
|
---|
49 | HREF="language.oop.magic-functions.html"
|
---|
50 | ACCESSKEY="P"
|
---|
51 | >Pøedcházející</A
|
---|
52 | ></TD
|
---|
53 | ><TD
|
---|
54 | WIDTH="80%"
|
---|
55 | ALIGN="center"
|
---|
56 | VALIGN="bottom"
|
---|
57 | >Kapitola 14. Classes and Objects</TD
|
---|
58 | ><TD
|
---|
59 | WIDTH="10%"
|
---|
60 | ALIGN="right"
|
---|
61 | VALIGN="bottom"
|
---|
62 | ><A
|
---|
63 | HREF="language.references.html"
|
---|
64 | ACCESSKEY="N"
|
---|
65 | >Dal¹í</A
|
---|
66 | ></TD
|
---|
67 | ></TR
|
---|
68 | ></TABLE
|
---|
69 | ><HR
|
---|
70 | ALIGN="LEFT"
|
---|
71 | WIDTH="100%"></DIV
|
---|
72 | ><DIV
|
---|
73 | CLASS="sect1"
|
---|
74 | ><H1
|
---|
75 | CLASS="sect1"
|
---|
76 | ><A
|
---|
77 | NAME="language.oop.newref"
|
---|
78 | ></A
|
---|
79 | >References inside the constructor</H1
|
---|
80 | ><P
|
---|
81 | > Creating references within the constructor can lead to confusing
|
---|
82 | results. This tutorial-like section helps you to avoid problems.
|
---|
83 |
|
---|
84 | <DIV
|
---|
85 | CLASS="informalexample"
|
---|
86 | ><A
|
---|
87 | NAME="AEN5790"
|
---|
88 | ></A
|
---|
89 | ><P
|
---|
90 | ></P
|
---|
91 | ><TABLE
|
---|
92 | BORDER="0"
|
---|
93 | BGCOLOR="#E0E0E0"
|
---|
94 | CELLPADDING="5"
|
---|
95 | ><TR
|
---|
96 | ><TD
|
---|
97 | ><PRE
|
---|
98 | CLASS="php"
|
---|
99 | >class Foo
|
---|
100 | {
|
---|
101 | function Foo($name)
|
---|
102 | {
|
---|
103 | // create a reference inside the global array $globalref
|
---|
104 | global $globalref;
|
---|
105 | $globalref[] = &$this;
|
---|
106 | // set name to passed value
|
---|
107 | $this->setName($name);
|
---|
108 | // and put it out
|
---|
109 | $this->echoName();
|
---|
110 | }
|
---|
111 |
|
---|
112 | function echoName()
|
---|
113 | {
|
---|
114 | echo "<br>",$this->name;
|
---|
115 | }
|
---|
116 |
|
---|
117 | function setName($name)
|
---|
118 | {
|
---|
119 | $this->name = $name;
|
---|
120 | }
|
---|
121 | }</PRE
|
---|
122 | ></TD
|
---|
123 | ></TR
|
---|
124 | ></TABLE
|
---|
125 | ><P
|
---|
126 | ></P
|
---|
127 | ></DIV
|
---|
128 | >
|
---|
129 | </P
|
---|
130 | ><P
|
---|
131 | > Let us check out if there is a difference between
|
---|
132 | <TT
|
---|
133 | CLASS="varname"
|
---|
134 | >$bar1</TT
|
---|
135 | > which has been created using
|
---|
136 | the copy <TT
|
---|
137 | CLASS="literal"
|
---|
138 | >=</TT
|
---|
139 | > operator and
|
---|
140 | <TT
|
---|
141 | CLASS="varname"
|
---|
142 | >$bar2</TT
|
---|
143 | > which has been created using
|
---|
144 | the reference <TT
|
---|
145 | CLASS="literal"
|
---|
146 | >=&</TT
|
---|
147 | > operator...
|
---|
148 |
|
---|
149 | <DIV
|
---|
150 | CLASS="informalexample"
|
---|
151 | ><A
|
---|
152 | NAME="AEN5797"
|
---|
153 | ></A
|
---|
154 | ><P
|
---|
155 | ></P
|
---|
156 | ><TABLE
|
---|
157 | BORDER="0"
|
---|
158 | BGCOLOR="#E0E0E0"
|
---|
159 | CELLPADDING="5"
|
---|
160 | ><TR
|
---|
161 | ><TD
|
---|
162 | ><PRE
|
---|
163 | CLASS="php"
|
---|
164 | >$bar1 = new Foo('set in constructor');
|
---|
165 | $bar1->echoName();
|
---|
166 | $globalref[0]->echoName();
|
---|
167 |
|
---|
168 | /* output:
|
---|
169 | set in constructor
|
---|
170 | set in constructor
|
---|
171 | set in constructor */
|
---|
172 |
|
---|
173 | $bar2 =& new Foo('set in constructor');
|
---|
174 | $bar2->echoName();
|
---|
175 | $globalref[1]->echoName();
|
---|
176 |
|
---|
177 | /* output:
|
---|
178 | set in constructor
|
---|
179 | set in constructor
|
---|
180 | set in constructor */</PRE
|
---|
181 | ></TD
|
---|
182 | ></TR
|
---|
183 | ></TABLE
|
---|
184 | ><P
|
---|
185 | ></P
|
---|
186 | ></DIV
|
---|
187 | >
|
---|
188 | </P
|
---|
189 | ><P
|
---|
190 | > Apparently there is no difference, but in fact there is a
|
---|
191 | very significant one: <TT
|
---|
192 | CLASS="varname"
|
---|
193 | >$bar1</TT
|
---|
194 | > and
|
---|
195 | <TT
|
---|
196 | CLASS="varname"
|
---|
197 | >$globalref[0]</TT
|
---|
198 | > are _NOT_ referenced, they
|
---|
199 | are NOT the same variable. This is because "new" does not
|
---|
200 | return a reference by default, instead it returns a copy.
|
---|
201 | <DIV
|
---|
202 | CLASS="note"
|
---|
203 | ><BLOCKQUOTE
|
---|
204 | CLASS="note"
|
---|
205 | ><P
|
---|
206 | ><B
|
---|
207 | >Poznámka: </B
|
---|
208 | >
|
---|
209 | There is no performance loss (since PHP 4 and up use reference
|
---|
210 | counting) returning copies instead of references. On the
|
---|
211 | contrary it is most often better to simply work with copies
|
---|
212 | instead of references, because creating references takes some
|
---|
213 | time where creating copies virtually takes no time (unless none
|
---|
214 | of them is a large array or object and one of them gets changed
|
---|
215 | and the other(s) one(s) subsequently, then it would be wise to
|
---|
216 | use references to change them all concurrently).
|
---|
217 | </P
|
---|
218 | ></BLOCKQUOTE
|
---|
219 | ></DIV
|
---|
220 | >
|
---|
221 | To prove what is written above let us watch the code below.
|
---|
222 |
|
---|
223 | <DIV
|
---|
224 | CLASS="informalexample"
|
---|
225 | ><A
|
---|
226 | NAME="AEN5804"
|
---|
227 | ></A
|
---|
228 | ><P
|
---|
229 | ></P
|
---|
230 | ><TABLE
|
---|
231 | BORDER="0"
|
---|
232 | BGCOLOR="#E0E0E0"
|
---|
233 | CELLPADDING="5"
|
---|
234 | ><TR
|
---|
235 | ><TD
|
---|
236 | ><PRE
|
---|
237 | CLASS="php"
|
---|
238 | >// now we will change the name. what do you expect?
|
---|
239 | // you could expect that both $bar1 and $globalref[0] change their names...
|
---|
240 | $bar1->setName('set from outside');
|
---|
241 |
|
---|
242 | // as mentioned before this is not the case.
|
---|
243 | $bar1->echoName();
|
---|
244 | $globalref[0]->echoName();
|
---|
245 |
|
---|
246 | /* output:
|
---|
247 | set from outside
|
---|
248 | set in constructor */
|
---|
249 |
|
---|
250 | // let us see what is different with $bar2 and $globalref[1]
|
---|
251 | $bar2->setName('set from outside');
|
---|
252 |
|
---|
253 | // luckily they are not only equal, they are the same variable
|
---|
254 | // thus $bar2->name and $globalref[1]->name are the same too
|
---|
255 | $bar2->echoName();
|
---|
256 | $globalref[1]->echoName();
|
---|
257 |
|
---|
258 | /* output:
|
---|
259 | set from outside
|
---|
260 | set from outside */</PRE
|
---|
261 | ></TD
|
---|
262 | ></TR
|
---|
263 | ></TABLE
|
---|
264 | ><P
|
---|
265 | ></P
|
---|
266 | ></DIV
|
---|
267 | >
|
---|
268 | </P
|
---|
269 | ><P
|
---|
270 | > Another final example, try to understand it.
|
---|
271 |
|
---|
272 | <DIV
|
---|
273 | CLASS="informalexample"
|
---|
274 | ><A
|
---|
275 | NAME="AEN5807"
|
---|
276 | ></A
|
---|
277 | ><P
|
---|
278 | ></P
|
---|
279 | ><TABLE
|
---|
280 | BORDER="0"
|
---|
281 | BGCOLOR="#E0E0E0"
|
---|
282 | CELLPADDING="5"
|
---|
283 | ><TR
|
---|
284 | ><TD
|
---|
285 | ><PRE
|
---|
286 | CLASS="php"
|
---|
287 | >class A
|
---|
288 | {
|
---|
289 | function A($i)
|
---|
290 | {
|
---|
291 | $this->value = $i;
|
---|
292 | // try to figure out why we do not need a reference here
|
---|
293 | $this->b = new B($this);
|
---|
294 | }
|
---|
295 |
|
---|
296 | function createRef()
|
---|
297 | {
|
---|
298 | $this->c = new B($this);
|
---|
299 | }
|
---|
300 |
|
---|
301 | function echoValue()
|
---|
302 | {
|
---|
303 | echo "<br>","class ",get_class($this),': ',$this->value;
|
---|
304 | }
|
---|
305 | }
|
---|
306 |
|
---|
307 |
|
---|
308 | class B
|
---|
309 | {
|
---|
310 | function B(&$a)
|
---|
311 | {
|
---|
312 | $this->a = &$a;
|
---|
313 | }
|
---|
314 |
|
---|
315 | function echoValue()
|
---|
316 | {
|
---|
317 | echo "<br>","class ",get_class($this),': ',$this->a->value;
|
---|
318 | }
|
---|
319 | }
|
---|
320 |
|
---|
321 | // try to undestand why using a simple copy here would yield
|
---|
322 | // in an undesired result in the *-marked line
|
---|
323 | $a =& new A(10);
|
---|
324 | $a->createRef();
|
---|
325 |
|
---|
326 | $a->echoValue();
|
---|
327 | $a->b->echoValue();
|
---|
328 | $a->c->echoValue();
|
---|
329 |
|
---|
330 | $a->value = 11;
|
---|
331 |
|
---|
332 | $a->echoValue();
|
---|
333 | $a->b->echoValue(); // *
|
---|
334 | $a->c->echoValue();
|
---|
335 |
|
---|
336 | /*
|
---|
337 | output:
|
---|
338 | class A: 10
|
---|
339 | class B: 10
|
---|
340 | class B: 10
|
---|
341 | class A: 11
|
---|
342 | class B: 11
|
---|
343 | class B: 11
|
---|
344 | */</PRE
|
---|
345 | ></TD
|
---|
346 | ></TR
|
---|
347 | ></TABLE
|
---|
348 | ><P
|
---|
349 | ></P
|
---|
350 | ></DIV
|
---|
351 | >
|
---|
352 | </P
|
---|
353 | ></DIV
|
---|
354 | ><DIV
|
---|
355 | CLASS="NAVFOOTER"
|
---|
356 | ><HR
|
---|
357 | ALIGN="LEFT"
|
---|
358 | WIDTH="100%"><TABLE
|
---|
359 | SUMMARY="Footer navigation table"
|
---|
360 | WIDTH="100%"
|
---|
361 | BORDER="0"
|
---|
362 | CELLPADDING="0"
|
---|
363 | CELLSPACING="0"
|
---|
364 | ><TR
|
---|
365 | ><TD
|
---|
366 | WIDTH="33%"
|
---|
367 | ALIGN="left"
|
---|
368 | VALIGN="top"
|
---|
369 | ><A
|
---|
370 | HREF="language.oop.magic-functions.html"
|
---|
371 | ACCESSKEY="P"
|
---|
372 | >Pøedcházející</A
|
---|
373 | ></TD
|
---|
374 | ><TD
|
---|
375 | WIDTH="34%"
|
---|
376 | ALIGN="center"
|
---|
377 | VALIGN="top"
|
---|
378 | ><A
|
---|
379 | HREF="index.html"
|
---|
380 | ACCESSKEY="H"
|
---|
381 | >Domù</A
|
---|
382 | ></TD
|
---|
383 | ><TD
|
---|
384 | WIDTH="33%"
|
---|
385 | ALIGN="right"
|
---|
386 | VALIGN="top"
|
---|
387 | ><A
|
---|
388 | HREF="language.references.html"
|
---|
389 | ACCESSKEY="N"
|
---|
390 | >Dal¹í</A
|
---|
391 | ></TD
|
---|
392 | ></TR
|
---|
393 | ><TR
|
---|
394 | ><TD
|
---|
395 | WIDTH="33%"
|
---|
396 | ALIGN="left"
|
---|
397 | VALIGN="top"
|
---|
398 | >The magic functions <TT
|
---|
399 | CLASS="literal"
|
---|
400 | >__sleep</TT
|
---|
401 | > and <TT
|
---|
402 | CLASS="literal"
|
---|
403 | >__wakeup</TT
|
---|
404 | ></TD
|
---|
405 | ><TD
|
---|
406 | WIDTH="34%"
|
---|
407 | ALIGN="center"
|
---|
408 | VALIGN="top"
|
---|
409 | ><A
|
---|
410 | HREF="language.oop.html"
|
---|
411 | ACCESSKEY="U"
|
---|
412 | >Nahoru</A
|
---|
413 | ></TD
|
---|
414 | ><TD
|
---|
415 | WIDTH="33%"
|
---|
416 | ALIGN="right"
|
---|
417 | VALIGN="top"
|
---|
418 | >Vysvìtlení referencí (odkazù)</TD
|
---|
419 | ></TR
|
---|
420 | ></TABLE
|
---|
421 | ></DIV
|
---|
422 | ></BODY
|
---|
423 | ></HTML
|
---|
424 | >
|
---|