destroying objects

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

destroying objects

Post by daedalus__ »

I'm trying to use this function to destroy objects.

It doesn't work but I do not know why.

I would like it to work but do not know how to make it work.

Can I not use references like that?

:(

Code: Select all

function Destroy(&$object)
{
	if ( is_object($object) )
	{
		unset($object);
	}
}
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

You're working in PHP 5 right? Objects are passed by reference already.

And unset() is all you need.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

Well, I have this service locator. It stores objects in an array like TNSG's does. I figured that I may want to remove an object from that array for some reason (maybe i only need it for a second) so I put that function in there.

So, I say something like this:

Code: Select all

$wrapper->destroy($wrapper->objects['test']);
I thought that, $wrapper->objects['test'] would be destroyed but it isn't.

I could just pass the keyname of the object and do it that way but I wanted to know if it would work when i referenced the object.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

PHP uses reference counting. If further references exist to the object, PHP will not destroy it.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

Is there that I can find all the references or something?

I'm just going to pass it the object name I guess, but I would still like to know.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

I don't believe there is a way. However, you could set an internal property that tells other instances to stop reacting and/or directly call the __destruct() method. If your class methods are built right, having the destructor called would short circuit them from processing things further.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

I don't know if this is what you meant but I tried:

Code: Select all

function destroy($object)
{
    $object->__destruct();
}
I had to add a __destruct() method to the class as well.

Might you be able to show an example of what you mean?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Yes, that is what I was talking about. The method would normally be called by PHP during actual destruction, but since you want to basically force destruction, you need to call it yourself and in some way short circuit any calls to other references to the object to, basically, self destruct as well.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

feyd wrote:in some way short circuit any calls to other references to the object to, basically, self destruct as well.
I'm having trouble understanding that because it should only exist in one place, and is not being used in the script anywhere other than the service locator.

Could this bit of code be making destructing it tricky?

Code: Select all

$this->object = $this->Instantiate($class_name, $args);
$this->objects[$object_name] = $this->object;
unset($this->object);
It's the only thing I can think of?
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

I'm just going to go ahead and pass the name of the object rather than a reference. It works.

It really bugs me that passing a reference isn't working though. I'd really like to figure it out. :P
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

When $this->objects[$object_name] is passed into destroy() you will effectively have two references to the object. Calling unset() will only destroy the local reference. However, if you set it to null, false, or something else you will overwrite the originally passed reference too. An example:

Code: Select all

[feyd@home]>php -r "$arr = array(); class foo{} $foo = new foo(); $arr[] = $foo; function nil(&$o){$o = null;} var_dump($arr,$foo); nil($arr[0]); var_dump($arr,$foo);"
array(1) {
  [0]=>
  object(foo)#1 (0) {
  }
}
object(foo)#1 (0) {
}
array(1) {
  [0]=>
  NULL
}
object(foo)#1 (0) {
}
Notice that the original object still exists because $foo has not been destroyed.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

So, set the reference to null or some other value and then destroy it?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Setting the reference to null or whatever effectively destroys the object by removing two references to it at once, but any further references will still hold the object untouched as I've said and shown before.
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Post by daedalus__ »

I guess that I am not understanding. I didn't understand the debugging thing you posted either.

I am going to work with it more tomorrow. :D
I'm tired.
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

Each object (amongst others) has a reference counter.
$obj = new MyClass(), new object, assigned to a variable, reference counter=1 (slightly simplified ;))
$o = $obj; increments that counter for the object $obj is pointing to, because $o is a new reference, counter=2
$obj = null;, one reference eliminated, reference counter 1. There's still a way to access the object.
$o = null; another reference is removed, reference counter 0, i.e. there's no way to reference that object anymore. php can and will collect the garbage.

not strictly but generally related: http://www.iecc.com/gclist/GC-faq.html
Post Reply