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