class Foo {
function Foo($name) {
// 在全局数组 $globalref 中建立一个引用
global $globalref;
$globalref[] = &$this; //globalref[0] 放进一个对象
// 将名字设定为传递的值
$this->setName($name);
// 并输出之
$this->echoName();
} function echoName() {
echo "<br />",$this->name;
//print_r($globalref);
} function setName($name) {
$this->name = $name;
}
}$bar1 = new Foo('set in constructor');
$bar1->setName('set from outside');$globalref[0]->echoName();$bar1->echoName();
你们觉得输出结果会是如何?理由呢?
function Foo($name) {
// 在全局数组 $globalref 中建立一个引用
global $globalref;
$globalref[] = &$this; //globalref[0] 放进一个对象
// 将名字设定为传递的值
$this->setName($name);
// 并输出之
$this->echoName();
} function echoName() {
echo "<br />",$this->name;
//print_r($globalref);
} function setName($name) {
$this->name = $name;
}
}$bar1 = new Foo('set in constructor');
$bar1->setName('set from outside');$globalref[0]->echoName();$bar1->echoName();
你们觉得输出结果会是如何?理由呢?
因此$this->name='set in constructo',而$this->echoName();则会输出 <br />set in constructo$bar1->setName('set from outside'); //第二次为$name属性赋值,覆盖前者。
因此输出两次 <br />set from outside
<br />set from outside
<br />set from outside有什么问题吗?
这里只改了 $bar1->setName('set from outside');
globalref[0] 为什么会被改变啊?
在构造函数中创建引用可能会导致混淆的结果。本节以教程形式帮助避免问题。
<?php
class Foo {
function Foo($name) {
// 在全局数组 $globalref 中建立一个引用
global $globalref;
$globalref[] = &$this;
// 将名字设定为传递的值
$this->setName($name);
// 并输出之
$this->echoName();
} function echoName() {
echo "<br />",$this->name;
} function setName($name) {
$this->name = $name;
}
}
?> 下面来检查一下用拷贝运算符 = 创建的 $bar1 和用引用运算符 =& 创建的 $bar2 有没有区别...
<?php
$bar1 = new Foo('set in constructor');
$bar1->echoName();
$globalref[0]->echoName();/* 输出:
set in constructor
set in constructor
set in constructor */$bar2 =& new Foo('set in constructor');
$bar2->echoName();
$globalref[1]->echoName();/* 输出:
set in constructor
set in constructor
set in constructor */
?> 显然没有区别,但实际上有一个非常重要的区别:$bar1 和 $globalref[0] 并没有被引用,它们不是同一个变量。这是因为“new”默认并不返回引用,而返回一个拷贝。
// 现在改个名字,你预期什么结果?
// 你可能预期 $bar1 和 $globalref[0] 二者的名字都改了...
$bar1->setName('set from outside');// 但如同前面说的,并不是这样。
$bar1->echoName();
$globalref[0]->echoName();/* 输出为:
set from outside
set in constructor */// 现在看看 $bar2 和 $globalref[1] 有没有区别
$bar2->setName('set from outside');// 幸运的是它们不但相同,根本就是同一个变量。
// 因此 $bar2->name 和 $globalref[1]->name 也是同一个变量。
$bar2->echoName();
$globalref[1]->echoName();/* 输出为:
set from outside
set from outside */
?>
谁说的?用&是引用,否则是一份拷贝
出现和运行不符合的结果没什么奇怪的.新的php5的oo的内容请看
http://www.php.net/manual/zh/language.oop5.php如果这里你发现在php5.4内运行和结果不符的代码,
请在这里贴出来或者直接报告到bugs.php.net谢谢
class SimpleClass
{
// 成员声明
public $var = 'a default value<br>'; // 方法声明
public function displayVar() {
echo $this->var;
}
}
$instance = new SimpleClass();$assigned = $instance; //副本拷贝给 $assigned;$reference =& $instance;// reference 直接引用到 $instance$instance->var = '$assigned will have this value';$instance = null; // $instance and $reference become nullvar_dump($instance);
var_dump($reference);
var_dump($assigned);?> 这里 $instance 和 $reference 不就是都指向同一个对象的引用吗?而$assigned 不是只获得了一份拷贝吗?否则 $instance = null; 之后,为什么 $assigned 却没受到影响呢?
$assigned = $instance;
$reference =& $instance;$instance->var = '$assigned will have this value';var_dump($instance);
var_dump($reference);
var_dump($assigned);得到
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned will have this value"
}
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned will have this value"
}
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned will have this value"
}
三个都一样,说明
$assigned = $instance;
是传递引用到 $assigned ,而不是将副本拷贝给 $assigned
否则 $assigned 不会跟随变化$instance = new SimpleClass();
是 $instance 对 new SimpleClass() 后的实体的引用$reference =& $instance;
是变量间的引用
所以一个变了,另一个也变了$assigned = $instance;
实际上是赋值,只不过值是一个引用
实际上是赋值,只不过值是一个引用"你意思是说 $assigned 引用的是 $instance 的值,而不是 $instance 这个对象本身?所以 $assigned 在 $instance=null 之后,仍然有值?
而reference是instance的引用, 间接指向了该对象
就是
instance---->&object
assigned---->&object
reference--->&instance-->&object而$instance=null后,
instance--->null
assigned---->&object 不变
reference--->&instance-->null所以assigned还是一样,没有变化
这时object还在,不会被销毁
如果assigned也=null了,该对象因为没有变量引用它,将会被垃圾收集.注意,这里$assigned=$instance不会创建一个新的object,
所以如果需要复制一个新对象,我们需要clone,请看我上面给你的手册oo部分希望我已经讲清楚了...
看这里吧
http://topic.csdn.net/u/20120430/17/f917e5b3-8447-42fa-8cbd-6d5a410cbedb.html