Что именно происходит при создании экземпляра с «новым»? - PullRequest
17 голосов
/ 29 декабря 2011

Давайте рассмотрим следующий код:

class a {
    public $var1;
    function disp(){
        echo $this->var1;
        }    
    }

$obj1 = new a;
echo '<br/>After instantiation into $obj1:<br/>';    
xdebug_debug_zval('obj1');  

$obj1->var1 = "Hello ";
echo '<br/><br/>After assigning "Hello" to  $obj->var1:<br/>';
$obj1->disp();

echo "<br/><br/>";  
xdebug_debug_zval('obj1');  

Вывод:

После создания экземпляра в $ obj1:obj1: (refcount = 1, is_ref = 0) = класс a {public $ var1 = (refcount = 2, is_ref = 0) = NULL}

После присвоения «Hello» $ obj-> var1:Привет

obj1: (refcount = 1, is_ref = 0) = класс a {public $ var1 = (refcount = 1, is_ref = 0) = 'Hello'}

Oneпо одному:

После создания экземпляра в $ obj1:obj1: (refcount = 1, is_ref = 0) = класс a {public $ var1 = (refcount = 2, is_ref = 0) = NULL}

Почему $obj1->var1 имеет refcount=2, когдаесть только один объект класса a?

Это из-за того, как оператор new выполняет присваивание?PHP делает назначение со ссылками.При создании экземпляра с new имя символа / переменной не ассоциируется с этим экземпляром.Но свойства класса имеют имена.Является ли recount=2 из-за этого?

Если это так, то произошла COW (копия при записи) с мелкой копией WRT экземпляра класса.Хотя свойства по-прежнему указывают на zval свойств, созданных во время создания экземпляра с помощью new.

Now,

После присвоения «Hello» $ obj-> var1:Привет

obj1: (refcount = 1, is_ref = 0) = класс a {public $ var1 = (refcount = 1, is_ref = 0) = 'Hello'}

Итак, когда я присваиваю значение свойству $obj1->var1 нового контейнера zval для этого свойства и, следовательно, refcount=1?

Означает ли это, что контейнер zval, созданный во время создания экземпляра с использованием new, все ещеживет, но недоступен, так как с ним не связано ни одного символа / имени переменной?

Обратите внимание (из xdebug: Функции отображения переменных ):debug_zval_dump() отличается от xdebug_debug_zval().

void xdebug_debug_zval ( [string varname [, ...]] )

Отображение информации о переменной .

Эта функция отображает структурированную информацию об одной или нескольких переменных, которая включает ее тип, значение и информацию о пересчете.Массивы исследуются рекурсивно со значениями.Эта функция реализована не так, как PHP-функция debug_zval_dump () , чтобы обойти проблемы, возникающие у этой функции, поскольку сама переменная фактически передается функции.Версия Xdebug лучше, так как она использует имя переменной для поиска переменной во внутренней таблице символов и напрямую обращается ко всем свойствам, не имея дело с фактической передачей переменной в функцию.В результате информация, которую возвращает эта функция, гораздо точнее, чем собственная функция PHP для отображения информации zval.

UPDATE: Dec 31th 2011:

Я пытаюсь посмотреть, как происходит распределение памяти, когда новый используется.Но есть слишком много других вещей, которые я должен сделать прямо сейчас.Я надеюсь, что скоро смогу опубликовать полезное обновление.До тех пор вот ссылки на код, на который я смотрел:

Ответы [ 2 ]

4 голосов
/ 29 декабря 2011

Добавление еще одного экземпляра $obj2 = new a; увеличивает refcount до 3, а не 4, поэтому это происходит в результате вызова xdebug_debug_zval. Цель функции xdebug - избежать путаницы при передаче переменной в функцию и (возможно) создании дополнительной ссылки.

К сожалению, это не относится к переменным-членам; другая ссылка создается на эти звалы для их экспорта. Поэтому все предостережения и запутанные обстоятельства, перечисленные в примечании к документации debug_zval_dump , по-прежнему применимы к переменным-членам.

2 голосов
/ 29 декабря 2011

Я думаю, что раздел «Примечание: Остерегайтесь пересчета» на следующей странице объясняет это: http://php.net/manual/en/function.debug-zval-dump.php

Это показывает, что количество ссылок увеличивается, если Zend оптимизирует способ его передачи, но затем возникает «предостережение», когда вызывается функция копирования при записи, возвращая счет обратно до 1.

Надеюсь, что помогает

...