PHP函数中的"&"运算符是如何工作的?

12
请看以下代码:
function addCounter(&$userInfoArray) {
    $userInfoArray['counter']++;
    return $userInfoArray['counter'];
}

$userInfoArray = array('id' => 'foo', 'name' => 'fooName', 'counter' => 10);
$nowCounter = addCounter($userInfoArray);

echo($userInfoArray['counter']);

这将显示11。

但是!如果在函数参数中删除"&"运算符,结果将为10。

发生了什么?


只用了3分钟就得到了2个完美的答案!你们都是天才吗?还是我应该问这个问题。太惊讶了! - Deckard
哦...我试着谷歌搜索了一下,但失败了...太尴尬了... - Deckard
4个回答

45
& 运算符告诉 PHP 在传递数组到函数时不要复制它。相反,对数组进行一个 引用 传递到函数中,这样函数就修改了原始数组而非其副本。

看这个最简单的例子:

<?php
function foo($a) { $a++; }
function bar(&$a) { $a++; }

$x = 1;
foo($x);
echo "$x\n";    
bar($x);
echo "$x\n";
?>

输出结果如下:

1
2

调用 foo 并没有修改 $x。另一方面,调用 bar 进行了修改。


我知道我有点晚了 - 但是非常感谢您提供的这个极其清晰的答案,没有任何疑问。 - Michael

8

在这里,&字符意味着变量是通过引用传递而不是值传递。两者之间的区别在于,如果您通过引用传递,对变量所做的任何更改也会反映在原始变量中。

function do_a_thing_v ($a) {
    $a = $a + 1;
}
$x = 5;
do_a_thing_v($x);
echo $x; // echoes 5

function do_a_thing_r (&$a) {
    $a = $a + 1;
}
$x = 5;
do_a_thing_v($x);
echo $x; // echoes 6

2
也许我可以补充其他答案,如果它是一个对象,那么它不是“作为值传递的对象”,而是“对象的引用作为值传递”(尽管我在评论中问“按引用传递对象”与“对象的引用按值传递”的区别是什么)。数组默认情况下是按值传递的。
信息:对象和引用 例子:
class Foo {
    public $a = 10;
}

function add($obj) {
    $obj->a++;
}

$foo = new Foo();
echo $foo->a, "\n";

add($foo);
echo $foo->a, "\n";

结果:

$ php try.php
10
11

谢谢你,另一个天才先生。 - Deckard
1
这是一个常见的错误。对象并不是通过引用传递的,而是通过值传递它们的引用。这是一个至关重要的区别!尝试修改引用本身,而不是实例成员(即在方法内部编写$obj = new Foo())。具有讽刺意味的是,您链接的页面甚至您的引用不正确!所以你一定知道你写了假话。 - Konrad Rudolph
如果是按引用传递,与按值传递其引用有何不同?如果在方法内部使用 $obj = new Foo(),结果是否相同?即,再次打印时,它仍然是 11 - nonopolarity
既然这是一个独立的项目,讨论一下在http://stackoverflow.com/questions/3957801/is-there-simple-php-code-to-distinguish-passing-the-object-as-reference-vs-pas如何? - nonopolarity

2
当在函数调用中使用变量前的&符号时,它与原始变量本身相关联。因此,您发布的代码表示它将向原始数组的计数器添加1。如果没有&符号,则会复制数据并添加到它,然后返回新的计数器11。旧数组仍保持不变为10,并返回的新计数器变量变为11。 http://www.phpreferencebook.com/samples/php-pass-by-reference/ 是一个很好的例子。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接