Unset all instances of an object PHP
object, php, unset
Solution
Automatic cleanup?
No, PHP isn't awared about your architecture. It will not remove objects "cascade", they are independent entities - and, more, can belong to different scopes, for example. Simple code:
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());
By the way, for copying you can use `clone` in PHP (that, however, will result in object cloning, obviously)
Simple way
Most simple way to resolve a matter is to iterate through `$GLOBALS`, checking it with `instanceof`. This has serious weakness: inner function/method scopes would not be affected:
//static since doesn't belong to any instance:
public static function cleanup()
{
foreach($GLOBALS as $name=>$var)
{
if($var instanceof self)
{
unset($GLOBALS[$name]);
}
}
}
-and
$foo = new Test(3);
$bar = $foo->getCopy();
var_dump($foo->getIdentity(), $bar->getIdentity());//valid
Test::cleanup();
//2 x notice:
var_dump($foo, $bar);
Note, that is has nothing to do with "child" mechanics (i.e. it will clean all instances in global scope - no matter which was copied from which).
Common case
Sample above will not do the stuff in common case. Why? Imagine that you'll have holder class:
class Holder
{
protected $obj = null;
public function __construct($obj)
{
$this->obj = $obj;
}
public function getData()
{
return $this->obj;
}
}
and you'll pass instance to it:
$foo = new Test(3);
$bar = $foo->getCopy();
$baz = new Holder($bar);
-so then you'll have no chances to handle even this simple situation in common case. And with more complex situations you will also be stuck.
What to do?
I'd recommend: destroy objects explicitly when you need to do that. Implicit unset is a side-effect, and even if you'll maintain that somehow (I can imagine Observer pattern + some global registry for that) - it will be horrible side-effect, that will kill readability for your code. And same is about code, that uses `$GLOBALS` I've written above - I do not recommend to act such way in any case.
Problem
I have a class with a method that returns a new instance of itself. This allows me to use one single object without having to declare new ones over and over with the same values. For those wondering why not extending the class or something else, it just makes my life easier and it works like a charm, but my final purpose is to remove them all in one line. for example: ``` $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` and `$bar` now share the same methods and values but those values can be modified separately. ``` $foo->changeName('newName'); $bar->changeName('newName2'); ``` My question here is, if I unset the first class created `unset($foo)` will PHP automatically unset the other instances `($bar)` or will the garbage collector remove them eventually? I have tested it by unsettling $foo and gives me an error when I call $foo but not when I call $bar. What I am trying to do is to unset all the instances of that class at once. Thanks.