Это было мое понимание на некоторое время, что foreach
клонирует отдельные объекты в своих итерациях, и я использовал &
итерировать по ссылке. Тем не менее, в моей последней машине, которая работает на PHP 5.5.10, я могу опустить &
и все еще обновлять оригинальный объект. Я не вижу ничего в примечаниях к выпуску. Я что-то неправильно понимаю?
foreach ($items as $item) { // No "&"$item->setData('123'); // Updates the respective object in $items
// Checked object ID hash, and they're the same with or without "&"}
PHP Change Log: http://php.net/ChangeLog-5.php
Парадигма PHP заключается в том, что объекты (и ресурсы) всегда ссылки, в то время как другие типы (базовые типы или массивы) копируются, поэтому &
Оператор не влияет на объекты (и не имеет смысла на ресурсы, так как только «специальные функции», то есть внешние библиотечные модули могут принимать их в качестве параметров), но позволяет передавать переменные других типов по ссылке.
В PHP объекты всегда передаются по ссылке. Как это работает? Объект имеет идентификатор, который передается, мы можем назвать это справиться. Так что если вы:
$a = new A();
$b = $a;
$b->foo = 2;
echo $a->foo;
возвращаемое значение будет 2
, Зачем? Поскольку справиться объекта копируется в $b
и они оба — $a
а также $b
— указать на тот же объект. Мы можем назвать это ссылкой, но это не означает, что это строгое значение ссылки, но поведение этой реализации похоже на ссылку. Поэтому вам не нужно использовать ссылки, потому что PHP делает это для вас по умолчанию.
Прочитайте OOP references documentation
.
Foreach назначает каждый элемент массива данной переменной, как в простом назначении, с =
, который копирует значение элемента в переменную. Это всегда верно независимо от того, какой тип имеет значение. (Только если вы делаете as &$item
это будет ссылка.)
$item
не «объект». $item
является ссылкой на объект, в основном указатель на объект. В PHP 5 вы не можете иметь переменную, значение которой «является объектом» — когда вы делаете new something()
вы получаете ссылку на объект; когда вы получаете доступ к полю или методу с ->
, левая сторона должна быть ссылкой на объект. По сути, вы всегда имеете дело со ссылками на объекты, а не с самими объектами.
Две ссылки на объекты могут указывать на один и тот же объект, и если вы измените объект, вызвав для него метод, используя одну ссылку на объект, результат будет виден через другую ссылку на объект, которая указывает на тот же объект.