language/references.xml
9463e5b660c4883b91a30f07ff68731bbcc48346
...
...
@@ -11,9 +11,10 @@
11
11
you cannot perform pointer arithmetic using them, they are not
12
12
actual memory addresses, and so on. See
13
13
<xref linkend="language.references.arent" /> for more
14
-
information. Instead, they are symbol table aliases. Note that in
15
-
PHP, variable name and variable content are different, so the same
16
-
content can have different names. The closest analogy is with
14
+
information. Instead, they are
15
+
<link linkend="features.gc.refcounting-basics">symbol table</link>
16
+
aliases. Note that in PHP, variable name and variable content are different, so the same
17
+
content can have different names. The closest analogy is with
17
18
Unix filenames and files - variable names are directory entries,
18
19
while variable content is the file itself. References can be
19
20
likened to hardlinking in Unix filesystem.
...
...
@@ -40,7 +41,9 @@
40
41
<programlisting role="php">
41
42
<![CDATA[
42
43
<?php
44
+

43
45
$a =& $b;
46
+

44
47
?>
45
48
]]>
46
49
</programlisting>
...
...
@@ -66,7 +69,8 @@ $a =& $b;
66
69
<programlisting role="php">
67
70
<![CDATA[
68
71
<?php
69
-
function foo(&$var) { }
72
+

73
+
function foo(&$var) {}
70
74

71
75
foo($a); // $a is "created" and assigned to null
72
76

...
...
@@ -74,9 +78,10 @@ $b = array();
74
78
foo($b['b']);
75
79
var_dump(array_key_exists('b', $b)); // bool(true)
76
80

77
-
$c = new StdClass;
81
+
$c = new stdClass();
78
82
foo($c->d);
79
83
var_dump(property_exists($c, 'd')); // bool(true)
84
+

80
85
?>
81
86
]]>
82
87
</programlisting>
...
...
@@ -85,27 +90,25 @@ var_dump(property_exists($c, 'd')); // bool(true)
85
90
</note>
86
91
<para>
87
92
The same syntax can be used with functions that return
88
-
references, and with the <literal>new</literal> operator (since PHP
89
-
4.0.4 and before PHP 5.0.0):
93
+
references:
90
94
<informalexample>
91
95
<programlisting role="php">
92
96
<![CDATA[
93
97
<?php
98
+

94
99
$foo =& find_var($bar);
100
+

95
101
?>
96
102
]]>
97
103
</programlisting>
98
104
</informalexample>
99
-
Since PHP 5, <link linkend="language.oop5.basic.new">new</link>
100
-
returns a reference automatically, so
101
-
using <literal>=&amp;</literal> in this context is deprecated and
102
-
produces an <constant>E_DEPRECATED</constant> message in PHP 5.3 and
103
-
later, and an <constant>E_STRICT</constant> message in earlier versions.
104
-
(Technically, the difference is that, in PHP 5, object variables, much like
105
-
resources, are a mere pointer to the actual object data, so these object
106
-
references are not "references" in the same sense used before (aliases).
107
-
For more information, see <link linkend="language.oop5.references">Objects
108
-
and references</link>.)
105
+
</para>
106
+
<para>
107
+
Using the same syntax with a function that does <emphasis>not</emphasis>
108
+
return by reference will give an error, as will using it with the result
109
+
of the <link linkend="language.oop5.basic.new">new</link> operator.
110
+
Although objects are passed around as pointers, these are not the same as references,
111
+
as explained under <link linkend="language.oop5.references">Objects and references</link>.
109
112
</para>
110
113
<warning>
111
114
<para>
...
...
@@ -117,12 +120,14 @@ $foo =& find_var($bar);
117
120
<programlisting role="php">
118
121
<![CDATA[
119
122
<?php
123
+

120
124
$var1 = "Example variable";
121
125
$var2 = "";
122
126

123
127
function global_references($use_globals)
124
128
{
125
129
global $var1, $var2;
130
+

126
131
if (!$use_globals) {
127
132
$var2 =& $var1; // visible only inside the function
128
133
} else {
...
...
@@ -132,8 +137,10 @@ function global_references($use_globals)
132
137

133
138
global_references(false);
134
139
echo "var2 is set to '$var2'\n"; // var2 is set to ''
140
+

135
141
global_references(true);
136
142
echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable'
143
+

137
144
?>
138
145
]]>
139
146
</programlisting>
...
...
@@ -152,12 +159,16 @@ echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable'
152
159
<programlisting role="php">
153
160
<![CDATA[
154
161
<?php
162
+

155
163
$ref = 0;
156
164
$row =& $ref;
165
+

157
166
foreach (array(1, 2, 3) as $row) {
158
-
// do something
167
+
// Do something
159
168
}
169
+

160
170
echo $ref; // 3 - last element of the iterated array
171
+

161
172
?>
162
173
]]>
163
174
</programlisting>
...
...
@@ -174,11 +185,16 @@ echo $ref; // 3 - last element of the iterated array
174
185
<programlisting role="php">
175
186
<![CDATA[
176
187
<?php
188
+

177
189
$a = 1;
178
190
$b = array(2, 3);
191
+

179
192
$arr = array(&$a, &$b[0], &$b[1]);
180
-
$arr[0]++; $arr[1]++; $arr[2]++;
193
+
$arr[0]++;
194
+
$arr[1]++;
195
+
$arr[2]++;
181
196
/* $a == 2, $b == array(3, 4); */
197
+

182
198
?>
183
199
]]>
184
200
</programlisting>
...
...
@@ -194,19 +210,21 @@ $arr[0]++; $arr[1]++; $arr[2]++;
194
210
<programlisting role="php">
195
211
<![CDATA[
196
212
<?php
213
+

197
214
/* Assignment of scalar variables */
198
215
$a = 1;
199
216
$b =& $a;
200
217
$c = $b;
201
-
$c = 7; //$c is not a reference; no change to $a or $b
218
+
$c = 7; // $c is not a reference; no change to $a or $b
202
219

203
220
/* Assignment of array variables */
204
221
$arr = array(1);
205
-
$a =& $arr[0]; //$a and $arr[0] are in the same reference set
206
-
$arr2 = $arr; //not an assignment-by-reference!
222
+
$a =& $arr[0]; // $a and $arr[0] are in the same reference set
223
+
$arr2 = $arr; // Not an assignment-by-reference!
207
224
$arr2[0]++;
208
225
/* $a == 2, $arr == array(2) */
209
226
/* The contents of $arr are changed even though it's not a reference! */
227
+

210
228
?>
211
229
]]>
212
230
</programlisting>
...
...
@@ -227,6 +245,7 @@ $arr2[0]++;
227
245
<programlisting role="php">
228
246
<![CDATA[
229
247
<?php
248
+

230
249
function foo(&$var)
231
250
{
232
251
$var++;
...
...
@@ -234,6 +253,7 @@ function foo(&$var)
234
253

235
254
$a=5;
236
255
foo($a);
256
+

237
257
?>
238
258
]]>
239
259
</programlisting>
...
...
@@ -264,11 +284,14 @@ foo($a);
264
284
<programlisting role="php">
265
285
<![CDATA[
266
286
<?php
287
+

267
288
function foo(&$var)
268
289
{
269
290
$var =& $GLOBALS["baz"];
270
291
}
292
+

271
293
foo($bar);
294
+

272
295
?>
273
296
]]>
274
297
</programlisting>
...
...
@@ -284,7 +307,7 @@ foo($bar);
284
307
available in the function <varname>foo</varname> (it is represented by
285
308
<varname>$var</varname>, but <varname>$var</varname> has only
286
309
variable contents and not name-to-value binding in the calling
287
-
symbol table).
310
+
<link linkend="features.gc.refcounting-basics">symbol table</link>).
288
311
You can use <link linkend="language.references.return">returning
289
312
references</link> to reference variables selected by the function.
290
313
</simpara>
...
...
@@ -299,14 +322,17 @@ foo($bar);
299
322
<programlisting role="php">
300
323
<![CDATA[
301
324
<?php
325
+

302
326
function foo(&$var)
303
327
{
304
328
$var++;
305
329
}
306
330

307
331
$a=5;
332
+

308
333
foo($a);
309
334
// $a is 6 here
335
+

310
336
?>
311
337
]]>
312
338
</programlisting>
...
...
@@ -315,11 +341,7 @@ foo($a);
315
341
<simpara>
316
342
There is no reference sign on a function call - only on
317
343
function definitions. Function definitions alone are enough to
318
-
correctly pass the argument by reference. As of PHP 5.3.0,
319
-
you will get a warning saying that "call-time pass-by-reference" is
320
-
deprecated when you use &amp; in <literal>foo(&amp;$a);</literal>.
321
-
And as of PHP 5.4.0, call-time pass-by-reference was removed, so
322
-
using it will raise a fatal error.
344
+
correctly pass the argument by reference.
323
345
</simpara>
324
346
</note>
325
347
</para>
...
...
@@ -331,11 +353,6 @@ foo($a);
331
353
Variables, i.e. <literal>foo($a)</literal>
332
354
</simpara>
333
355
</listitem>
334
-
<listitem>
335
-
<simpara>
336
-
New statements, i.e. <literal>foo(new foobar())</literal>
337
-
</simpara>
338
-
</listitem>
339
356
<listitem>
340
357
<para>
341
358
References returned from functions, i.e.:
...
...
@@ -343,16 +360,20 @@ foo($a);
343
360
<programlisting role="php">
344
361
<![CDATA[
345
362
<?php
363
+

346
364
function foo(&$var)
347
365
{
348
366
$var++;
349
367
}
368
+

350
369
function &bar()
351
370
{
352
371
$a = 5;
353
372
return $a;
354
373
}
374
+

355
375
foo(bar());
376
+

356
377
?>
357
378
]]>
358
379
</programlisting>
...
...
@@ -371,24 +392,32 @@ foo(bar());
371
392
<programlisting role="php">
372
393
<![CDATA[
373
394
<?php
395
+

374
396
function foo(&$var)
375
397
{
376
398
$var++;
377
399
}
400
+

378
401
function bar() // Note the missing &
379
402
{
380
403
$a = 5;
381
404
return $a;
382
405
}
383
-
foo(bar()); // Produces fatal error since PHP 5.0.5
406
+

407
+
foo(bar()); // Produces a notice
384
408

385
409
foo($a = 5); // Expression, not variable
386
410
foo(5); // Produces fatal error
411
+

412
+
class Foobar {}
413
+

414
+
foo(new Foobar()) // Produces a notice as of PHP 7.0.7
415
+
// Notice: Only variables should be passed by reference
416
+

387
417
?>
388
418
]]>
389
419
</programlisting>
390
420
</informalexample>
391
-
These requirements are for PHP 4.0.4 and later.
392
421
</para>
393
422
</sect1>
394
423

...
...
@@ -405,18 +434,22 @@ foo(5); // Produces fatal error
405
434
<programlisting role="php">
406
435
<![CDATA[
407
436
<?php
408
-
class foo {
437
+

438
+
class Foo
439
+
{
409
440
public $value = 42;
410
441

411
-
public function &getValue() {
442
+
public function &getValue()
443
+
{
412
444
return $this->value;
413
445
}
414
446
}
415
447

416
-
$obj = new foo;
417
-
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42.
448
+
$obj = new Foo();
449
+
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42
418
450
$obj->value = 2;
419
-
echo $myValue; // prints the new value of $obj->value, i.e. 2.
451
+
echo $myValue; // Prints the new value of $obj->value, i.e. 2
452
+

420
453
?>
421
454
]]>
422
455
</programlisting>
...
...
@@ -441,38 +474,57 @@ echo $myValue; // prints the new value of $obj->value, i.e. 2.
441
474
work as you are attempting to return the result of an
442
475
<emphasis>expression</emphasis>, and not a variable, by reference. You can
443
476
only return variables by reference from a function - nothing else.
444
-
Since PHP 4.4.0 in the PHP 4 branch, and PHP 5.1.0 in the PHP 5 branch, an
445
-
<constant>E_NOTICE</constant> error is issued if the code tries to return
446
-
a dynamic expression or a result of the <literal>new</literal> operator.
447
477
</simpara>
448
478
</note>
449
479
<para>
450
-
To use the returned reference, you must use reference assigment:
480
+
To use the returned reference, you must use reference assignment:
451
481
<informalexample>
452
482
<programlisting role="php">
453
483
<![CDATA[
454
484
<?php
455
-
function &collector() {
456
-
static $collection = array();
457
-
return $collection;
485
+

486
+
function &collector()
487
+
{
488
+
static $collection = array();
489
+
return $collection;
458
490
}
491
+

459
492
$collection = &collector();
493
+
// Now the $collection is a referenced variable that references the static array inside the function
494
+

460
495
$collection[] = 'foo';
496
+

497
+
print_r(collector());
498
+
// Array
499
+
// (
500
+
// [0] => foo
501
+
// )
502
+

461
503
?>
462
504
]]>
463
505
</programlisting>
464
506
</informalexample>
507
+
<note>
508
+
<simpara>
509
+
If the assignment is done without the <literal>&amp;</literal> symbol, e.g. <code>$collection = collector();</code>,
510
+
the <varname>$collection</varname> variable will receive a copy of the value, not the reference returned by the function.
511
+
</simpara>
512
+
</note>
465
513
To pass the returned reference to another function expecting a reference
466
514
you can use this syntax:
467
515
<informalexample>
468
516
<programlisting role="php">
469
517
<![CDATA[
470
518
<?php
471
-
function &collector() {
472
-
static $collection = array();
473
-
return $collection;
519
+

520
+
function &collector()
521
+
{
522
+
static $collection = array();
523
+
return $collection;
474
524
}
525
+

475
526
array_push(collector(), 'foo');
527
+

476
528
?>
477
529
]]>
478
530
</programlisting>
...
...
@@ -496,9 +548,11 @@ array_push(collector(), 'foo');
496
548
<programlisting role="php">
497
549
<![CDATA[
498
550
<?php
551
+

499
552
$a = 1;
500
553
$b =& $a;
501
554
unset($a);
555
+

502
556
?>
503
557
]]>
504
558
</programlisting>
...
...
@@ -531,7 +585,9 @@ unset($a);
531
585
<programlisting role="php">
532
586
<![CDATA[
533
587
<?php
588
+

534
589
$var =& $GLOBALS["var"];
590
+

535
591
?>
536
592
]]>
537
593
</programlisting>
...
...
@@ -542,14 +598,6 @@ $var =& $GLOBALS["var"];
542
598
won't unset the global variable.
543
599
</simpara>
544
600
</sect2>
545
-

546
-
<sect2 xml:id="references.this">
547
-
<title><literal>$this</literal></title>
548
-
<simpara>
549
-
In an object method, <varname>$this</varname> is always a reference
550
-
to the caller object.
551
-
</simpara>
552
-
</sect2>
553
601
</sect1>
554
602

555
603
</chapter>
556
604