在php中取消设置引用处的变量

在php中取消设置引用处的变量,php,reference,Php,Reference,我有一个类,它包含一个对象数组,并具有通过引用从该数组返回对象的方法。还有一种方法可以从数组中取消设置对象 但是,如果我有一个引用数组中某个对象的变量,并且该元素未设置,那么该变量仍然有一个对它的引用。在remove方法中,我需要做什么才能永久销毁该对象,包括对它的引用 class myClass { public $objectList = array(); public function __construct() { $objectList[] =

我有一个类,它包含一个对象数组,并具有通过引用从该数组返回对象的方法。还有一种方法可以从数组中取消设置对象

但是,如果我有一个引用数组中某个对象的变量,并且该元素未设置,那么该变量仍然有一个对它的引用。在remove方法中,我需要做什么才能永久销毁该对象,包括对它的引用

class myClass
{
    public $objectList = array();

    public function __construct()
    {
        $objectList[] = new myObject();
    }

    public function &getObjectByReference()
    {
         return $this->objectList[0];
    }

    public function removeObject()
    {
        unset($this->objectList[0]);
    }
}
$myClass = new myClass();
$referencedObject = $myClass->getObjectByReference(); 
// this can now use the methods from myObject
$myClass-> removeObject(); 
// supposed to delete the object from memory. However $referencedObject is still
// able to use all the methods from myObject.
这就是我遇到的问题,我需要能够从数组中删除对象并从内存中删除该对象,以便引用该对象的变量不再可用。

您是否尝试过:

$referencedObject = &$myClass->getObjectByReference();

$referencedObject在输入&?

后是否仍然存在要从返回值创建引用,函数必须通过引用返回(您已经这样做了),赋值必须通过引用返回。所以你应该写:

$referencedObject =& $myClass->getObjectByReference();
如果这样做,引用将被销毁


但是,如果您想销毁所有以该对象为值的变量(并且是而不是引用),那么这是不可能的。只能删除实际引用,不能删除具有相同值的变量;)

Php正在使用垃圾收集器:如果仍然存在对该对象的引用,则不会删除该对象

unset($this->objectList[0])
不删除对象,但删除$this->objectList中的值,该对象仍然存在,因为它被$referencedObject引用


一个解决方案是:当你删除对象时,告诉他他正在被删除,并且在该对象中有一个布尔值“isDeleted”。然后,对于该对象的每个方法,检查isDeleted是否为true,在这种情况下,什么也不做。

这就是PHP垃圾收集器的本质。为了确保调用者不维护对您的对象的引用,您必须确保他们永远不会接触原始对象。这里有一个想法:

class myClass
{
    public $objectList = array();

    public function __construct()
    {
        $objectList[] = new Wrapper(new myObject());
    }

    public function getObject()
    {
         return $this->objectList[0];
    }

    public function removeObject()
    {
        $this->objectList[0]->emptyWrapper();
        unset($this->objectList[0]);
    }
}



class Wrapper {

    private $object;

    public function __construct($object) {
        $this->object = $object;
    }

    public function __call($method, $args) {
        return call_user_func_array(array($this->object, $method), $args);
    }

    public function __get($attr) {
        return $this->object->$attr;
    }

    public function __set($attr, $value) {
        $this->object->$attr = $value;
    }

    public function emptyWrapper() {
        $this->object = null;
    }

}
您可以使用此包装器思想,也可以使用强制间接寻址和句柄。我可能更喜欢使用强制间接方式;否则,调用方仍然可以使包装器对象保持活动状态——尽管它相当便宜

class myClass
{
    public $objectList = array();

    public function __construct()
    {
        $objectList[] = new myObject();
    }

    public function getObjectHandle() {
        return 0;
    }

    public function removeObject($h)
    {
        unset($this->objectList[$h]);
    }

    public function call($h, $method, $args) {
        call_user_func(array($this->objectList[$h], $method), $args);
    }

    public function get($h, $attr) {
        return $this->objectList[$h]->$attr;
    }

    public function set($h, $attr, $value) {
        $this->objectList[$h]->$attr = $value;
    }

}

$myClass = new myClass();
$objectHandle = $myClass->getObjectHandle();
// example method call
$myClass->call($objectHandle, 'some_method', array('arg1', 'arg2')); 
$myClass->removeObject($objectHandle);

我试着这样做,但是当调用print\r($referencedObject)时,它仍然显示它的所有成员变量,所以它不能消失?