Как работает оператор "&" в функции PHP?

Пожалуйста, смотрите этот код:

function addCounter(&$userInfoArray) {
    $userInfoArray['counter']++;
    return $userInfoArray['counter'];
}

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

echo($userInfoArray['counter']);

Это покажет 11.

Но! Если вы удалите оператор "&" в параметре функции, результат будет равен 10.

Что происходит?

Ответ 1

Оператор & сообщает 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 сделал.

Ответ 2

Здесь символ & означает, что переменная передается по ссылке вместо по значению. Разница между ними заключается в том, что если вы пройдете по ссылке, любые изменения, внесенные в переменную, также будут сделаны в оригинале.

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

Ответ 3

При использовании амперсанда до переменной в вызове функции он ассоциируется с самой исходной переменной. При этом код, который вы опубликовали, говорит, что он добавит 1 к счетчику исходного массива. Без амперсанда он берет копию данных и добавляет к ней, а затем возвращает новый счетчик 11. Старый массив по-прежнему остается нетронутым в 10, а новая возвращаемая переменная возвращается в 11.

http://www.phpreferencebook.com/samples/php-pass-by-reference/

- хороший пример.

Ответ 4

Может быть, я могу добавить к другим ответам, что если это объект, то это не "объект, переданный как значение", но это "ссылка на объект передается как значение" (хотя я спрашиваю, что разница между "объектом передается по ссылке", а "ссылка на объект передается по значению" в комментариях). По умолчанию массив передается по значению.

Информация: Объекты и ссылки

Пример:

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