用'new'实例化时到底发生了什么?

Thi*_*key 17 php reference new-operator php-internals

我们考虑以下代码:

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');  
Run Code Online (Sandbox Code Playgroud)

输出:

实例化到$ obj1之后:
obj1:(refcount = 1,is_ref = 0)= class a {public $ var1 =(refcount = 2,is_ref = 0)= NULL}

将"Hello"分配给$ obj-> var1:
Hello

obj1:(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->var1refcount=2当有一个类只有一个对象?

是因为new操作员如何进行作业?PHP使用引用进行赋值.实例化时new,没有符号/变量名与该实例相关联.但是,类属性确实有名称.是recount=2因为这个吗?

如果是这种情况,则发生COW(写入时复制),并使用浅拷贝WRT类实例.虽然属性仍然指向在实例化期间使用创建的zval属性new.

现在,

将"Hello"分配给$ obj-> var1:
Hello

obj1:(refcount = 1,is_ref = 0)= class a {public $ var1 =(refcount = 1,is_ref = 0)='Hello'}

那么,当我为属性分配一个值为该属性$obj1->var1的新zval容器,因此refcount=1

这是否意味着在实例化期间使用new静态生成的zval容器仍然存在但由于没有与之关联的符号/变量名称而无法访问?

请注意(来自xdebug:变量显示功能):
debug_zval_dump()不同于xdebug_debug_zval().

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

显示有关变量的信息.

此函数显示有关一个或多个变量的结构化信息,包括其类型,值和引用计数信息.使用值递归地探索数组.此函数的实现与PHP的debug_zval_dump()函数不同,以便解决该函数所具有的问题,因为变量本身实际上已传递给函数.Xdebug的版本更好,因为它使用变量名来查找内部符号表中的变量并直接访问所有属性,而无需处理实际将变量传递给函数.结果是该函数返回的信息比PHP自己显示zval信息的函数准确得多.

UPDATE : Dec 31th 2011:

我试图看看在使用new时如何进行内存分配.但是我现在还有太多其他的事要做.我希望我能尽快发布有用的更新.在此之前,这里是我正在查看的代码链接:

cmb*_*ley 4

添加另一个实例化$obj2 = new a;会将引用计数增加到 3,而不是 4,因此这是调用 xdebug_debug_zval 的结果。xdebug 函数的目的是避免将变量传递到函数中并(可能)创建额外的引用而造成混乱。

不幸的是,这不适用于成员变量;创建对这些 zval 的另一个引用以便导出它们。因此, debug_zval_dump 文档注释中列出的所有警告和令人困惑的情况仍然适用于成员变量。

  • 看一下 [xdebug_var.c](https://github.com/derickr/xdebug/blob/master/xdebug_var.c):对象元素的变量导出处理输出。 (2认同)