Рассмотрим следующий код:
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) = class a {public $var1 = (refcount = 2, is_ref = 0) = NULL}После назначения" Hello "в $obj- > var1:
Helloobj1: (refcount = 1, is_ref = 0) = class a {public $var1 = (refcount = 1, is_ref = 0) = 'Hello'}
Один за другим:
После создания экземпляра в $obj1:
obj1: (refcount = 1, is_ref = 0) = class a {public $var1 = (refcount = 2, is_ref = 0) = NULL}
Почему $obj1->var1
имеет refcount=2
, когда есть только один объект класса a?
Это из-за того, как оператор new
выполняет присвоение?
PHP выполняет задание со ссылками. При создании экземпляра с помощью new
имя символа/переменной не ассоциируется с этим экземпляром. Но свойства класса имеют имена. Из-за этого существует recount=2
?
Если это так, то CO.W(копирование при записи) произошел с неглубокой копией WRT экземпляра класса. Хотя свойства все еще указывают на zval свойств, созданных во время создания, используя new
.
Теперь,
После назначения "Hello "в $obj- > var1:
Helloobj1: (refcount = 1, is_ref = 0) = class 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:
Я пытаюсь посмотреть, как распределение памяти происходит, когда используется новый. Но сейчас слишком много других вещей, которые я должен сделать прямо сейчас. Надеюсь, что скоро опубликую полезное обновление. До тех пор вот ссылки на код, на который я смотрел: