php对象引用和析构函数的关系

时间:2020-12-07 15:51:27

  在php中构造函数和析构函数都属于魔术方法,比如构造函数在某一个类中,当这个类被实例化的时候就会自动调用,而析构函数是在这个类的对象被销毁的时候自动调用,默认情况下是在程序执行结束时自动调用。

  如果我们对对象进行了引用,那么析构函数调用也会改变,如果只实例化了一个对象,比如是$obj那么只要有$obj = null;这个语句时,就表示对象$obj被销毁,这个时候析构函数会被提前调用,但这个类的其他对象不受影响。

  如果我们使用$obj1 = &$obj;即使用&符号引用赋值的操作,这个操作不会产生对象的一个新的引用,这所谓的两个对象其实使用同一内存堆空间,当$obj或者$obj1其中一个被销毁时,另一个同时也会消失。

  如果使用$obj1 = $obj;操作时,这是直接赋值操作,会产生一个对象的一个新的引用,当$obj或者$obj1其中一个被销毁时,析构函数不会被执行,另外一个对象还可以正常使用,两个都销毁时,析构函数才会执行,这说明两者还是统一的关系,不是两个对象,而是一个引用关系,这个引用操作并不是创建一个互不干扰的新对象,而是引用一个对象,当其中一个对象的成员改变时,另外一个对象的成员随之改变并且相互关联,所以直接用=赋值是介于=&操作和clone操作之间的一种情况。

  如果进行clone操作,就是$obj1 = clone $obj;这种操作,$obj1和$obj是两个对象,之间不受任何干扰,改变一个成员不影响另一个成员,在clone是$obj1所有的成员属性值都完全和$obj一样,这才是真正意义上的复制。复制时还可以在类里面写上__clone()魔术方法,给$obj1某些属性一个新值或屏蔽不想要的值,实现方法简单的举个例子。

 class Player{
public $name;
function __destruct(){
echo "Destroying ".$this->name."<br />";
}
//设置魔术方法,赋值时会自动调用这里的属性值,作用是初始化值,或屏蔽不想要的值
function __clone(){
$this->name="gbcs";
}
}
$james=new Player();
$james2=clone $james;
echo $james2->name.'<br />';
$james->name="james";
$james2->name="james2";
echo $james->name.'<br />';
$james=null;
echo $james2->name.'<br />';

执行结果如下:

php对象引用和析构函数的关系

根据执行结果可以清楚地看到,clone产生两个彼此独立的对象,并且也调用了魔术方法__clone(),从析构函数执行顺序也可以看出,两个对象是分开销毁的,和赋值的意义是不同的。