取消设置对象PHP的所有实例

我有一个带有返回自己的新实例的方法的类.
这使我可以使用一个对象,而不必一遍又一遍地使用相同的值声明新的对象.对于那些想知道为什么不扩大班级或其他目的的人,这只是使我的生活更轻松,并且它像一种魅力,但是我的最终目的是将它们全部删除.

例如:

$foo = new myClass('name1','ab','cd');
$bar = $foo->duplicate();

//duplicate() saves the new object in itself in an array:
array_push($this->instance,new myClass('name1','ab','cd'));
//and returns a pointer to the saved instance.
return end($this->instance);

$foo和$bar现在共享相同的方法和值,但是可以分别修改这些值.

$foo->changeName('newName'); 

$bar->changeName('newName2');

我的问题是,如果我取消设置创建的第一个类unset($foo),PHP将自动取消设置其他实例($bar),还是垃圾收集器最终将其删除?

我已经通过使$foo不稳定来测试了它,并在调用$foo时给了我一个错误,但在调用$bar时却没有给我一个错误.

我想做的是立即取消设置该类的所有实例.

谢谢.

解决方法:

自动清理?

不,PHP不了解您的体系结构.它不会删除“级联”对象,它们是独立的实体-例如,可以属于不同的范围.简单的代码:

class Test
{
   protected $id = null;
   protected $uniqid = null;

   public function __construct($id)
   {
      $this->id = $id;//user-passed variable
      $this->uniqid = uniqid();//internal: to identify instance 
   }

   public function getCopy()
   {
      return new self($this->id);
   }

   public function getIdentity()
   {
      return $this->uniqid;
   }
}

$foo = new Test(3);
$bar = $foo->getCopy();
var_dump($foo->getIdentity());//valid

unset($foo);
//still valid: bar has nothing to do with foo
var_dump($bar->getIdentity());

顺便说一句,对于复制,您可以在PHP中使用clone(但是,显然,这将导致对象克隆)

简单的方法

解决问题的最简单方法是遍历$GLOBALS,并使用instanceof对其进行检查.这具有严重的弱点:内部功能/方法范围将不受影响:

//static since doesn't belong to any instance:
public static function cleanup()
{
   foreach($GLOBALS as $name=>$var)
   {
      if($var instanceof self)
      {
         unset($GLOBALS[$name]);
      }
   }
}

-和

$foo = new Test(3);
$bar = $foo->getCopy();
var_dump($foo->getIdentity(), $bar->getIdentity());//valid
Test::cleanup();
//2 x notice:
var_dump($foo, $bar);

请注意,这与“子级”机制无关(即,它将清除全局范围内的所有实例-无论从哪个副本中复制了该实例).

常见情况

上面的示例在通常情况下不会做这些事情.为什么?想象一下,您将拥有持有人类别:

class Holder
{
   protected $obj = null;

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

   public function getData()
   {
      return $this->obj;
   }
}

然后将实例传递给它:

$foo = new Test(3);
$bar = $foo->getCopy();
$baz = new Holder($bar);

-因此,在通常情况下,即使是这种简单情况,您也没有机会处理.而在更复杂的情况下,您也将陷于困境.

该怎么办?

我建议:在需要时明确销毁对象.隐式未设置是一个副作用,即使您将以某种方式保持该状态(我可以想象Observer对其进行某些全局注册表设置)-这将是可怕的副作用,这将破坏代码的可读性.关于代码的问题也是如此,它使用了我上面编写的$GLOBALS-无论如何,我不建议您这样做.

上一篇:有关php unset函数的问题


下一篇:SwiftUI中的快捷键积累