Примечание: этот ответ на the question as originally asked. Новый вопрос несколько иной, хотя использование объектов в этом случае не меняет фундаментального поведения.
Ссылки PHP не могут быть «закольцованы» - оператор =&
не похож на механизм ссылки/де-ссылки указателя, он связывает две (или более) переменные вместе. Но не важно, что ни одно имя переменной не является более «реальным», чем другое. Это как (или все) ссылки на безымянное значение.
Например, $foo =& $bar
принимает значение, на который указывает $bar
и также точек $foo
при этом значении. Если вы затем назначаете любую переменную (например, $foo = 42;
или $bar = 42;
), значение обновляется. Некоторые действия, такие как unset($bar)
, действуют на переменную , а не значение, поэтому они влияют только на эту конкретную переменную, а не на ссылочное значение.
Вы можете увидеть это в действии, выполнив это: $foo = 42; $bar =& $foo; unset($foo); echo $bar;
Обратите внимание, что $foo
было «оригинальным» именем для значения, но даже после его отмены значение все еще существует. Затем вы можете повторно использовать переменную $foo
для совершенно другого значения, не влияя на $bar
.
Если вы берете переменную, которая уже была ссылкой, и делаете ее ссылкой на что-то еще, это похоже на отмену ссылки и повторное использование имени переменной для установки нового. Таким образом, значение не затронуто, и ранее упоминавшиеся имена переменных становятся независимыми.
В коде, вы делаете это: (. В качестве технических подробностей, что я называю здесь «ценность» является структурой в рамках внутреннего РНР называется zval
)
// 1: Make $values['a'] point to the value currently pointed at by $values['b']
$values['a'] =& $values['b'];
// 2: Make $values['b'] point to the value currently pointed at by $values['c']
// the previous value is now only pointed to by $values['a']
$values['b'] =& $values['c'];
// 3: Set the value shared by $values['b'] and $values['c'] to 1
$values['c'] = 1;
Edit для обновления вопроса:
объектов могут показаться, чтобы сделать это более сложным, так как у них есть дополнительного уровня косвенности, который работает почти Точно так же: $foo = new A('a'); $bar = $foo;
все еще создает два значения (zval
s), но эти значения оба указателя на тот же объект .
В вашем случае, это не имеет никакого значения, так как вы все еще используете ссылочное назначение (=&
) - и если вы не делали, вы получите тот же результат:
// 1: Make the value of $values['a'] point to the object currently pointed at by the value of $values['b']
$values['a'] = $values['b'];
// 2: Make the value of $values['b'] point to the object currently pointed at by the value of $values['c']
// the previous object is now only pointed to by the value of $values['a']
$values['b'] = $values['c'];
Теперь у нас есть три вещей мы можем изменить: в переменную, значениеэто указывает на, и объект, что это указывает на:
// Change the object: updates the object shared by $values['b'] and $values['c']
$values['c']->value = 42;
// Change the value: will only update $values['b'] if =& was used to tie them together
$values['c'] = 42;
// Change the variable: will never affect $values['b']
unset($values['c']);
Я думаю, что сначала нужно установить 'b' и' c', иначе для каждой ссылки не нужно ничего. Попробуйте инициализировать их в первой строке с фиктивными значениями? – halfer
Вы не можете просто изменить свой вопрос таким решительным образом. Любой комментарий или ответ сразу же ошибочны или, по крайней мере, запутывают будущих посетителей. –
На самом деле, я думаю, что ваш первый вопрос был в любом случае лучше: смешивание объектов и эталонных переменных, подобных этому, просто смущает вопрос, но основной принцип тот же. – IMSoP