是否可以通过执行特定类的代码来取消设置(清理或取消实例化)该类的对象?
我的场景是,出于某种原因,我达到了一个地步,即该对象不再存在,所以我想通过杀死记忆中的引用来确保它不会再次被使用。
下面是一个片段示例:
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"来实现这一点,但都没有成功。
任何想法都非常欢迎。
干杯,
考虑到不能显式销毁对象。
允许PHP垃圾收集器对对象进行操作的方法有:
$var = null; // set to null
unset($var); // unset
物体将停留在那里。但是,如果取消设置对象,并且脚本将PHP推到内存限制,则不需要的对象将被垃圾收集。我会选择unset(),因为它的接缝可以获得更好的性能(没有经过测试,但在PHP官方手册的一条评论中有记录)。
也就是说,请记住,PHP总是在提供页面后立即销毁对象。因此,这应该只在非常长的循环和/或密集的页面上需要。
unset($o)
出了什么问题?如果这种行为真的冒犯了你,你可以把它封装在一个静态类方法中:
class Foo {
public static function destroy(&$foo) {
unset($foo);
}
}
Foo::destroy($o);
由于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
这是不可能的。您可以取消设置变量或将其设置为null,但不能保证您不会对该对象有任何引用($b = $o;
$b不会被unset($o);
破坏)。
一个丑陋的解决方案是在类中添加一个字段,例如destroyed
,在每个方法中检查它是否为true,如果为true则抛出异常。
是的,似乎不可能实现。。。另一种肮脏的方式可能是:
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...
但是,对象仍然存在,方法仍然可以访问。
您可以使用:
public function delete()
{
foreach($GLOBALS as $name => $value) {
if ($GLOBALS[$name] === $this) {
unset($GLOBALS[$name]);
}
}
}
任何PHP版本。只有当对象在全局范围内时,这才有效。