@HeBonpoc

(PHP5) Почему присваивание работает как клонирование?

Код с этой страницы php.net/manual/ru/language.oop5.basic.php из примера #4
<?php

$instance = new SimpleClass();

$assigned   =  $instance;
$reference  =& $instance;

$instance->var = '$assigned будет иметь это значение';

$instance = null; // $instance и $reference становятся null

var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>

Результат
NULL
NULL
object(SimpleClass)#1 (1) {
   ["var"]=>
     string(30) "$assigned будет иметь это значение"
}

А есть ещё клонирование php.net/manual/ru/language.oop5.cloning.php
Я правильно понял, что клонирование без определённого в классе метода __clone() делает тоже самое, что и обычное присваивание? Я вообще ожидал в этом примере, что $assigned будет NULL, а на деле как-будто написали $assigned = clone $instance;
Так в чём же разница?
  • Вопрос задан
  • 2419 просмотров
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Нету тут никакой магии с клонированием.

Для начала давайте разберемся что хранит $instance. Хранит оно ССЫЛКУ на объект а не сам объект. При простом присвоении по значению происходит копирование значения переменной, а оно у нас просто ссылка на объект. В итоге у нас уже две ссылки на один объект.

При присвоении переменной $reference значения по ссылке, у нас две переменные делят одно и тоже значение. А значение это - ссылка на объект.

Когда мы затираем ссылку в $instance, то есть мы меняем значение оной, оно же меняется и у $reference так как они делят на двоих одно значение. $assigned же имеет свою ссылку на объект.

$instance = new SimpleClass(); // количество ссылок на экземпляр SimpleClass - 1

$assigned   =  $instance; // количество ссылок на экземпляр SimpleClass - 2
$reference  =& $instance; // количество ссылок на экземпляр SimpleClass - 2

$instance = null; // количество ссылок на экземпляр SimpleClass - 1


Как только у нас не останется ссылок на экземпляр класса, сборщик мусора удалит объект.

А что до клона - если бы объекты бы копировались, начался бы ад, так как объекты хранят другие объекты, которые могут делить между другими объектами... словом там слишком сложно все становится и пусть уж лучше программист это в __clone сам разруливает.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
anyd3v
@anyd3v
Читайте документацию php.net/manual/en/language.operators.assignment.php

там описана разница
Assignment Operators
...
Note that the assignment copies the original variable to the new one (assignment by value), so changes to one will not affect the other. This may also have relevance if you need to copy something like a large array inside a tight loop.
...
Assignment by Reference
...
Assignment by reference means that both variables end up pointing at the same data, and nothing is copied anywhere.
...

по-моему все предельно ясно. в первом случае создается копия, во втором берется ссылка и переменная ссылается на тот же объект.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы