在函数名前面加上 &
的含义是什么?
这是否意味着 $result
是按引用返回而不是按值返回的?
如果是的话,那正确吗?我记得你不能返回一个对局部变量的引用,因为一旦函数退出它就消失了。
function &query($sql) {
// ...
$result = mysql_query($sql);
return $result;
}
这样的语法在实践中用在哪里呢?
这是否意味着
$result
是通过引用而不是值返回的?
是的。
那么这种语法在实践中在哪里使用?
这在PHP 4脚本中更为普遍,因为默认情况下对象是按值传递的。
class FooBar {
private $properties = array();
public function &__get($name) {
return $this->properties[$name];
}
public function __set($name, $value) {
$this->properties[$name] = $value;
}
}
&
,这是不可能的:$foobar = new FooBar;
$foobar->subArray = array();
$foobar->subArray['FooBar'] = 'Hallo World!';
PHP会抛出一个错误,例如“无法间接修改重载属性”,而不是执行操作。
好吧,这可能只是一个绕过PHP中某些设计缺陷的技巧,但它仍然很有用。
但是,老实说,我现在想不到另一个例子。但我敢打赌还有一些罕见的用例......
这是否意味着
$result
是通过引用而不是值返回的?
不是的。区别在于它可以通过引用返回。例如:
<?php
function &a(&$c) {
return $c;
}
$c = 1;
$d = a($c);
$d++;
echo $c; //echoes 1, not 2!
<?php
function &a(&$c) {
return $c;
}
$c = 1;
$d = &a($c);
$d++;
echo $c; //echoes 2
还有这种语法在实践中用在哪里?
在实践中,当你想让调用方操作被调用方拥有的数据而不告诉他时,你使用它。这很少被使用,因为它违反了封装原则——你可以将返回的引用设置为任何你想要的值;被调用方无法验证它。
nikic给出了一个很好的例子,说明了这种语法何时会在实践中使用。
<?php
// You may have wondered how a PHP function defined as below behaves:
function &config_byref()
{
static $var = "hello";
return $var;
}
// the value we get is "hello"
$byref_initial = config_byref();
// let's change the value
$byref_initial = "world";
// Let's get the value again and see
echo "Byref, new value: " . config_byref() . "\n"; // We still get "hello"
// However, let’s make a small change:
// We’ve added an ampersand to the function call as well. In this case, the function returns "world", which is the new value.
// the value we get is "hello"
$byref_initial = &config_byref();
// let's change the value
$byref_initial = "world";
// Let's get the value again and see
echo "Byref, new value: " . config_byref() . "\n"; // We now get "world"
// If you define the function without the ampersand, like follows:
// function config_byref()
// {
// static $var = "hello";
// return $var;
// }
// Then both the test cases that we had previously would return "hello", regardless of whether you put ampersand in the function call or not.
$a = new stdClass; $a->prop='foo'; function test($b){ $b->prop = 'bar'; } test($a); echo $a->prop;
正如你所看到的,对象是通过引用传递的 :) - Dennis Haarbrink