PHP: Чем ссылки не являются - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Передача по ссылке Что делают ссылки

Last updated: Sat, 27 Jan 2007

view this page in

# Чем ссылки не являются

Как уже было сказано, ссылки не являются указателями. Это означает, что следующая конструкция не будет делать то, что вы ожидаете:

`<?php
function foo(&$var)
{
$var =& $GLOBALS["baz"];
}
foo($bar);
?>`

Переменная `$var` в фукнции `foo` будет связана с `$bar` в вызывателе, но затем она будет перепривязана к `$GLOBALS["baz"]`. Нет способа связать `$bar` в области видимости вызывателя с чем-либо ещё путём использования механизма ссылок, поскольку `$bar` не доступна в функции `foo` (доступно лишь её значение через `$var`). Вы можете воспользоваться возвращением ссылок из функции для привязки внешней перменной к другому значению.

add a note User Contributed Notes
Чем ссылки не являются
Stevel
03-Feb-2007 08:30
`The manual states: "There's no way to bind $bar in the calling scope to something else using the reference mechanism"
This is actually incorrect. It is possible to bind $bar to another object. The given example doesn't work for obvious reasons: $var is redeclared as an alias for $GLOBALS["baz"], instead of an alias for $bar.
You should use an ordinary assignment to assign another object to the same variable. This works because variables containing objects actually contain a reference to that object, and the reference is copied to $var, and therefore is copied to $bar as well.
When using primitive values, such as integers or strings, the values itself are copied. In the example (when excluding the ampersand from the assignment), suppose that $GLOBALS['baz'] contains the value 3, after calling foo($bar), $bar will contain the integer 3, but they won't point to the same memory space.
The correct sentence would be thus:
"There's no way make $bar in the calling scope an alias for something else using the reference mechanism"`
Tee Cee
20-Aug-2006 05:59
`You can think of references as pointers, if you translate a=b into "*a = *b" and a =& b into "a=b".
Let's translate to C:
<?PHP
const int c_1 = 1, c_2 = 2;
int * a = &c_1;
int * b = &c_2;
void foo (int * var)
{
var = a;
}
?>
Here, it's obvious that calling foo(b) won't change the value of a, because var is a copy of b. You also have to be careful: order does matter. I could draw a diagram, but I won't.
<?php
$b=1; $d=2;
$a =& $b;
$c =& $d;
// now a=b=1; c=d=2;
$b =& $c;
// now a=1, b=c=d=2;
?>
It's also important to treat =& as its own operator, though you can stick spaces in the middle. The & does not bind to the variable, as shown by
<?php
$a = (&$b); // parse error
?>`
jagatpreet
30-Jan-2006 11:27
`In response to the example by mdiricks.
Extending the example given by mdiricks, the following code provides an explains the concept of re-referencing that is involved in making a call to function foo with the prototype foo(& var):
<!-- C re-referenced -->
<?
$a = 'eh';
$b = & $a;// $b == 'eh'
$c = & $b;// $c == 'eh'
$d = 'meh';
echo "\$a = $a\n";
echo "\$b = $b\n";
echo "\$c = $c\n";
echo "\$d = $d\n";
$c = & $d ;// $c == 'meh'
echo "\n";
echo "\$a = $a\n";
echo "\$b = $b\n";
echo "\$c = $c\n";
echo "\$d = $d\n";
?>
<!-- Value of c changed -->
<?
$a = 'eh';
$b = & $a;// $b == 'eh'
$c = & $b;// $c == 'eh'
$d = 'meh';
echo "\$a = $a\n";
echo "\$b = $b\n";
echo "\$c = $c\n";
echo "\$d = $d\n";
$c = 'meh' ;// $c == 'meh'. And also, $a = $b == 'meh'
echo "\n";
echo "\$a = $a\n";
echo "\$b = $b\n";
echo "\$c = $c\n";
echo "\$d = $d\n";
?>
This results in the following o/p:
<!-- C re-referenced -->
$a = eh
$b = eh
$c = eh
$d = meh
$a = eh
$b = eh
$c = meh
$d = meh
<!-- Value of c changed -->
$a = eh
$b = eh
$c = eh
$d = meh
$a = meh
$b = meh
$c = meh
$d = meh`
DanielSan88
27-Oct-2005 08:10
`I can see why there is a big debate on this. I'm hoping this will clarify it a little.
In PHP, as far as I can understand, when you assign a variable in the first place,
that variable is a refrence to the value that the variable contains.
<?php
$var = "String"; // Creates the string "String" somewhere in memory.
echo $var;
/* When the echo function is called, it pulls the value of $var out of memory from wherever PHP decided to put it.
PHP then ships this value off to your standard output. */
?>
Anyway, when you create a reference to the variable $var,
it doesn't reference the variable's name, but rather its contents.
For example:
<?php
$var2 = & $var;
echo $var2;
/* Calling this echo does ecactly the same thing as the echo in the code snippet above this one.
Whether you echo $var or $var2, the same string in memory is sent to your standard output. */
?>
In the same sense of an array, $var and $var2 are like keys to the same value. The value being the string in memory.
When you call a function that uses a reference, the reference is not less than the variable given as the argument, or anything more than it.
It is that same variable except with a different name.`
mdirks at gulfstreamcoach dot com
21-Oct-2005 08:40
`Here's a thought to settle the whole (are/aren't) debacle...
References are *like* pointers, but are not *identical to* pointers. The best comparison I could give is that references are "scope-limited pointers". You can change the value of one variable by changing the other as long as it is in the same scope. Once you set outside that scope (i.e. calling a function), references cease to act the same as pointers.
Example 1:
$a = 'eh';
$b = & $a;// $b == 'eh'
$c = & $b;// $c == 'eh'
$a = 'meh';// $c == 'meh'
... changing a's value will change c's value. This is where references are like pointers in C/C++
Example 2:
$GLOBALS["b"] = 'b_val';
$c = 'c_val';
function foo (&$var)
{
$var =& $GLOBALS["b"]; //affects only 'var' copy
}
$GLOBALS["b"] = & $a; // $GLOBALS["b"] == 'a_val'
foo($c); // the value of c will remain 'c_val'
... It might help to think of it in a different way. A calling the function by reference mimics the following behavior:
$var = & $c;
... so when you if you execute this line in foo():
$var =& $GLOBALS["b"];
, you are just re-referencing var from what it was "referenced to" at the function call to a new reference.
This is where references are *not* like pointers in C/C++ as the value of c is not changed as it would be if a similiar function that implemented pointers were used.
I hope this clears up the confusion.`
mstasak at access4less dot net
11-Jul-2005 07:18
`Note references in array elements behave very much the same as pointers. The following seems to defy the simple definition of array assignment as copy-by-value:
unset($a);
unset($b);
$a[1]=1;
$a[2]=&$a[1];
$b=$a;
$b[2]=7;
print_r($a);
Array
(
[1] => 7
[2] => 7
)
print_r($b);
Array
(
[1] => 7
[2] => 7
)
- so array assignment is a very shallow copy-by-value, which preserves reference associations in any array elements. Oddly, I believe PHP lacks a deep array-copy-by-value function.`
fzamperini_at_tin.it
16-Jun-2005 02:35
`References are not like pointers.
If you try the example above in C/C++ you will find that after calling foo(var) you can get or set the value of $GLOBALS["baz"] by reading or writing variable 'var' (I didn't actually try it, but I vaguely remember it works this way).
In PHP this is also true if you do:
<?PHP
$var =& $GLOBALS["baz"];
?>
but *IT IS NOT* if you use a function to do that, in spite of
- using a reference as a parameter (function foo(&$var)) and
- assigning it a reference to the variable you want to bind ($var =& $GLOBALS["baz"]) inside the function
I tried this:
<?PHP
$GLOBALS["baz"] = 'globals_baz';
$bar = 'bar';
function foo (&$var)
{
$var =& $GLOBALS["baz"];
}
// Before 'binding' $bar to $GLOBALS["baz"] using a function
echo '$GLOBALS[baz]: ' . $GLOBALS["baz"] . "<BR>\n"; // Output is 'globals_baz'
echo "\$bar: $bar <BR>\n"; // Output is 'bar'
foo($bar);
// After (what you may expected to be a) binding you should see that $bar is the same as $GLOBALS[baz]:
echo "\$bar: $bar <BR>\n"; // it didn't work: output is still 'bar' (not 'globals_baz')
// And setting $bar should set $GLOBALS[baz]:
$bar = 'bar';
echo '$GLOBALS[baz]: ' . $GLOBALS["baz"] . "<BR>\n"; // it didn't work, too: output is still 'globals_baz' (not 'bar')
?>
If you change the calling of foo($bar) with $bar =& $GLOBALS["baz"]; it all works as expected.
So the assertion, "references are not like pointers," might be a bit confusing but it is fair.`
nicolas at serpe dot org
24-May-2004 10:47
`About ansonyumo at email dot com second example, output will be 99, not 9.`
ansonyumo at email dot com
28-Feb-2004 01:47
`The assertion, "references are not like pointers," is a bit confusing.
In the example, the author shows how assigning a reference to a formal parameter that is also a reference does not affect the value of the actual parameter. This is exactly how pointers behave in C. The only difference is that, in PHP, you don't have to dereference the pointer to get at the value.
-+-+-
int bar = 99;
void foo(int* a)
{
a = &bar;
}
int main()
{
int baz = 1;
foo(&baz);
printf("%d\n", baz);
return 0;
}
-+-+-
The output will be 1, because foo does not assign a value to the dereferenced formal parameter. Instead, it reassigns the formal parameter within foo's scope.
Alternatively,
-+-+-
int bar = 99;
void foo(int* a)
{
*a = bar;
}
int main()
{
int baz = 1;
foo(&baz);
printf("%d\n", baz);
return 0;
}
-+-+-
The output will be 9, because foo dereferenced the formal parameter before assignment.
So, while there are differences in syntax, PHP references really are very much like pointers in C.
I would agree that PHP references are very different from Java references, as Java does not have any mechanism to assign a value to a reference in such a way that it modifies the actual parameter's value.`
schultz __at__ widescreen __dot__ ch
26-Jan-2004 07:57
`A not so simple Workaround...but still doable...have fun
class My{
var $value;
function get1(&$ref){
$ref[] =& $this;
}
function get2(&$ref){
$ref =& $this;
}
function get3(&$ref){
$ref = $this;
}
}
$m = new My();
$m->value = 'foo';
$m->get1($ref=array());
$m1 =& $ref[0];
$m1->value = 'bar';
echo "\n".'Works but is ugly...';
echo "\n".' m:'. get_class($m) . '->value = '. $m->value;
echo "\n".' m1:'. get_class($m1) . '->value = '. $m1->value;
echo "\n".'Does not work because references are not pointers...';
$m->value = 'foo';
$m->get2($m2);
$m2->value = 'bar';
echo "\n".' m:'. get_class($m) . '->value = '. $m->value;
echo "\n".' m2:'. get_class($m2) . '->value = '. $m2->value;
$m->value = 'foo';
$m->get3($m3);
$m3->value = 'bar';
echo "\n".'Does not work becuase it is set to a copy';
echo "\n".' m:'. get_class($m) . '->value = '.$m->value;
echo "\n".' m3:'. get_class($m3) . '->value = '. $m3->value;`
christian at kno dot at
12-Oct-2001 06:04
`As said above references are not pointers.
Following example shows a difference between pointers and references.
This Code
<?
$b = 1;
$a =& $b;
print("<pre>");
print("\$a === \$b: ".(($a === $b) ? "ok" : "failed")."\n");
print("unsetting \$a...\n");
unset($a);
print("now \$a is ".(isset($a) ? "set" : "unset")." and \$b is ".(isset($b) ? "set" : "unset")."\n");
print("</pre>");
$b = 1;
$a =& $b;
print("<pre>");
print("\$a === \$b: ".(($a === $b) ? "ok" : "failed")."\n");
print("unsetting \$b...\n");
unset($b);
print("now \$a is ".(isset($a) ? "set" : "unset")." and \$b is ".(isset($b) ? "set" : "unset")."\n");
print("</pre>");
?>
will produce this output:
---------
$a === $b: ok
unsetting $a...
now $a is unset and $b is set
$a === $b: ok
unsetting $b...
now $a is set and $b is unset
---------
So you see that $a and $b are identical ($a === $b -> true), but if one of both is unset, the other is not effected.`
add a note
Передача по ссылке Что делают ссылки

Last updated: Sat, 27 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 09:32:46 2007 PST