【发布时间】:2012-01-31 08:04:41
【问题描述】:
class a {
public $test="msg1";
}
$t1 = new a;
echo "echo1: After Instantiation :<br/>";
xdebug_debug_zval('t1');echo "<br/><br/>";
$t2 = $t1;
echo 'echo2: After assigning $t1 to $t2 :<br/>';
xdebug_debug_zval('t2');echo "<br/><br/>";
$t1->test="msg2";
echo 'echo3: After assigning $t1->test = "msg2" :<br/>';
xdebug_debug_zval('t1');echo "<br/>";
xdebug_debug_zval('t2');echo "<br/><br/>";
$t2->test="msg3";
echo 'echo4: After assigning $t2->test="msg3" :<br/>';
xdebug_debug_zval('t1');echo "<br/>";
xdebug_debug_zval('t2');echo "<br/><br/>";
$t2->test2 = "c*ap!";
echo 'echo5: After injecting $test2 to $t2 :<br/>';
xdebug_debug_zval('t1');echo "<br/>";
xdebug_debug_zval('t2');echo "<br/><br/>";
输出:
echo1:实例化后:
t1: (refcount=1, is_ref=0)=class a { public $test = (refcount=2, is_ref=0)='msg1' }echo2:将 $t1 分配给 $t2 后:
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=2, is_ref=0)='msg1' }echo3:分配 $t1->test = "msg2" 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }echo4:分配 $t2->test="msg3" 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }echo5:将 $test2 注入 $t2 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3'; public $test2 = (refcount=1, is_ref=0)='cap!' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3'; public $test2 = (refcount=1, is_ref=0)='cap!' }
忽略 echo1 和 echo2,因为:What is exactly happening when instantiating with 'new'? 和预期行为。
考虑echo3:
echo3:分配 $t1->test = "msg2" 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg2' }
这是可以理解的,因为我只是更改了$t1->test 变量,而没有直接更改为&t2->test。
考虑到echo4,直接更改为$t2->test:
echo4:分配 $t2->test="msg3" 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg3' }
没有 C.O.W 发生!即使未设置is_ref,更改也会反映到$t1。
考虑echo5,其中变量$test2被注入$t2:
echo5:将 $test2 注入 $t2 后:
t1: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg4'; public $test2 = (refcount=1, is_ref=0)='cap!' }
t2: (refcount=2, is_ref=0)=class a { public $test = (refcount=1, is_ref=0)='msg4'; public $test2 = (refcount=1, is_ref=0)='cap!' }
再一次,没有 C.O.W 发生!即使未设置is_ref,更改也会反映到$t1。
Why is this behaviour!?
【问题讨论】:
标签: php reference php-internals