(PHP)从类代码中取消设置对象

时间:2012-01-19 06:24:01

标签: php oop

是否可以通过执行该特定类的代码来取消设置(清除或取消实例化)类的对象?

我的场景是,出于某种原因,我达到了这个对象没有任何意义存在的点,所以我想确保通过在内存中删除它的引用来不再使用它。

以下是一个代码段示例:

class Foo {
    public $bar = "doh!";
    function destroy() {
        // ???    
    }
}
$o = new Foo();
echo $o->bar . '\n';
$o->destroy();
echo $o->bar . '\n'; // I expect an error here...

如果我在类代码之外执行“unset”命令,那么显然可行:

$o = new Foo();
unset($o);
echo $o->bar . '\n'; // PHP Notice:  Undefined property: Foo::$bar in ...

但我尝试在“destroy”方法中执行此操作,通过调用“unset”或创建自定义“__destruct”,但没有一个工作。

非常欢迎任何想法。

干杯,

6 个答案:

答案 0 :(得分:5)

考虑到您无法明确销毁某个对象

允许PHP垃圾收集器对对象进行操作的方法是:

$var = null; // set to null
unset($var); // unset

对象将留在那里。但是,如果取消设置对象并且脚本将PHP推送到内存限制,则不需要的对象将被垃圾回收。我会选择unset(),因为它接缝会有更好的性能(not tested but documented on one of the comments from the PHP official manual)。

那就是说要记住,PHP总是在提供页面时销毁对象。所以这应该只需要很长的循环和/或密集的页面。

答案 1 :(得分:1)

unset($o)出了什么问题?如果真的冒犯了你,你可以用静态类方法包装那个行为:

class Foo {
    public static function destroy(&$foo) {
        unset($foo);
    }
}
Foo::destroy($o);

答案 2 :(得分:1)

从php 5.2开始,可以使用spl_object_hash,但不应该使用它......

class MyClass {
    public function destroy(){
        foreach($GLOBALS as $k => $v){
            // bucabay is totally right ! It's faster this way
            //if(is_object($v) && (spl_object_hash($v) == spl_object_hash($this))){
            if($v === $this){
                    $GLOBALS[$k] = null;
                    return;
            }
        }
    }
}
$a = new MyClass;
$b = new MyClass;

var_dump($a, $b); // class MyClass#1 (0) {}class MyClass#2 (0) {}
echo "\n";

$a->destroy();
var_dump($a, $b); // NULL class MyClass#2 (0) {}
echo "\n";

$b->destroy();
var_dump($a, $b); // NULL NULL

答案 3 :(得分:0)

这是不可能的。您可以取消设置变量或将其设置为null,但不能保证您不会对此对象有任何引用($b = $o; $ b不会被unset($o);销毁。)

丑陋的解决方案是在您的课程中添加一个字段,例如destroyed,检查每个方法都不正确,如果是,则抛出异常。

答案 4 :(得分:0)

是的,似乎无法实现......另一种肮脏的方式可能是:

class Foo {
    public $bar = "doh!";
    function destroy() {
        unset($this->bar); // and do this for EVERY property of this class
    }
}
$o = new Foo();
echo $o->bar . '\n';
$o->destroy();
echo $o->bar . '\n'; // PHP Notice:  Undefined property: Foo::$bar in...

但是,该对象仍然存在,方法仍然可以访问。

答案 5 :(得分:0)

您可以使用:

public function delete()
    {
        foreach($GLOBALS as $name => $value) {
            if ($GLOBALS[$name] === $this) {
                unset($GLOBALS[$name]);
            }
        }
    }

任何PHP版本。这仅在对象位于全局范围内时才有效。