Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(PHP)从类代码中取消设置对象_Php_Oop - Fatal编程技术网

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

(PHP)从类代码中取消设置对象,php,oop,Php,Oop,是否可以通过执行特定类的代码来取消设置(清除或取消实例化)类的对象 我的场景是这样的,由于某种原因,我到达了一个点,即对象不再存在,因此我想通过在内存中删除它的引用来确保它不会被再次使用 以下是一个代码片段示例: class Foo { public $bar = "doh!"; function destroy() { // ??? } } $o = new Foo(); echo $o->bar . '\n'; $o->destro

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

我的场景是这样的,由于某种原因,我到达了一个点,即对象不再存在,因此我想通过在内存中删除它的引用来确保它不会被再次使用

以下是一个代码片段示例:

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”或创建一个自定义的“uu destroct”来实现这一点,但都没有成功

任何想法都是非常受欢迎的


干杯,

取消($o)有什么问题吗?如果这种行为真的冒犯了您,您可以将其封装在静态类方法中:

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

考虑到不能显式销毁对象

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

$var = null; // set to null
unset($var); // unset
物体将停留在那里。但是,如果您取消设置对象,并且脚本将PHP推到内存限制,则不需要的对象将被垃圾收集。我会选择unset(),因为它可以获得更好的性能()


也就是说,请记住,PHP总是在提供页面后立即销毁对象。因此,这应该只需要在非常长的循环和/或密集的页面上使用。

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


一个丑陋的解决方案是在类中添加一个字段,例如,
销毁
,检查每个方法是否为真,如果为真,则抛出异常。

是的,似乎不可能实现。。。另一种肮脏的方式可能是:

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...

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

由于PHP5.2,可以使用,但不应该使用

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
您可以使用:

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

任何PHP版本。仅当对象在全局范围内时,此选项才有效。

您取消设置了什么,您能写出准确的行吗?。可能的重复将不起作用
unset
在这种情况下,只删除一个引用,而不是对象本身。但可能
$foo=null将完成这项工作的想法是,在某个特定的情况下,对象应该停止存在,但是这个决定是由位于类本身的代码做出的。。。因此,关键是您不知道应该从实例化对象的角度终止该对象。使用
unset
永远不会带来更好的性能。不调用函数总是比调用it@zerkms除非您的脚本占用大量内存,否则在执行过程中可能需要清理。在那个特定的场景中。。。应该使用unset。然而,如果您不需要它,就不应该使用它,因为它不会加快速度。“除非您的脚本占用大量内存,否则在执行过程中,在某个时候它将需要清理”——这一切都是关于这样一个事实,否则脚本将根本无法工作。使用
unset
释放一些内存!=使用
unset
使脚本更快。@zerkms同意。但我很困惑,OP指的是速度吗?关于我的问题,我确实说“这应该只用于……等等”。性能不仅与速度有关,还与计算机资源消耗有关;)您只需与PHP5.2之前的===进行比较。($v==$this)