Похоже, что в PHP объекты передаются по ссылке. Даже операторы присваивания не создают копию объекта.
Вот простое, надуманное доказательство:
<?php
class A {
public $b;
}
function set_b($obj) { $obj->b = "after"; }
$a = new A();
$a->b = "before";
$c = $a; //i would especially expect this to create a copy.
set_b($a);
print $a->b; //i would expect this to show 'before'
print $c->b; //i would ESPECIALLY expect this to show 'before'
?>
В обоих случаях я получаю «после»
Итак, как мне передать $ a в set_b () по значению, а не по ссылке?
php
copy
clone
shallow-copy
Ник Стинамантес
источник
источник
(object) ((array) $objectA)
может привести к таким же желаемым результатам с лучшей производительностью, чем использованиеclone $objectA
илиnew stdClass
.Ответы:
В PHP 5+ объекты передаются по ссылке. В PHP 4 они передаются по значению (поэтому во время выполнения он передавался по ссылке, что устарело).
Вы можете использовать оператор «клон» в PHP5 для копирования объектов:
Кроме того, это просто объекты, которые передаются по ссылке, а не все, как вы сказали в своем вопросе ...
источник
$a = new stdClass; $b =& $a; $a = 42; var_export($b);
здесь$b
ссылка на переменную$a
; если вы замените=&
его нормальным=
, это не ссылка, а указатель на исходный объект.Ответы обычно можно найти в книгах по Java.
клонирование: если вы не переопределяете метод клонирования, по умолчанию используется мелкая копия. Если ваши объекты имеют только примитивные переменные-члены, это нормально. Но в языке без типов с другим объектом в качестве переменных-членов это головная боль.
сериализации / десериализации
$new_object = unserialize(serialize($your_object))
Это позволяет получить глубокое копирование с большими затратами в зависимости от сложности объекта.
источник
$a = clone $b
без магических__clone()
методов в игре) эквивалентна просмотру каждого из свойств объекта$b
в термине и присвоению того же свойства в новом члене того же класса, используя=
, Свойства, которые являются объектами, не получатclone
d, равно как и объекты внутри массива; то же самое касается переменных, связанных ссылкой; все остальное является просто значением и копируется, как при любом назначении.Call to method __clone from invalid context
:)__clone
метод, как указано в stackoverflow.com/a/186191/1614903 ниже. См. Phpinternalsbook.com/php5/zvals/memory_management.html для подробного объясненияСогласно предыдущему комментарию, если у вас есть другой объект в качестве переменной-члена, сделайте следующее:
Теперь вы можете заняться клонированием:
источник
Согласно документам ( http://ca3.php.net/language.oop5.cloning ):
источник
Просто для пояснения, PHP использует copy при записи, поэтому в основном все является справочной, пока вы не измените ее, но для объектов вам нужно использовать clone и магический метод __clone (), как в принятом ответе.
источник
Этот код помогает клонировать методы
источник
Я делал некоторые тесты и получил это:
источник
В этом примере мы создадим класс iPhone и сделаем его точную копию путем клонирования.
источник
Если вы хотите полностью скопировать свойства объекта в другом экземпляре, вы можете использовать эту технику:
Сериализуйте его в JSON, а затем удалите сериализацию обратно в Object.
источник