user23127
user23127

Reputation: 847

When (at which moment) is __destruct called?

Is there some assurance when __destruct is called, when considering simple objects without reference cycles? I know from java, that it is not defined when and if the function finalize is called, it depends on the garbage collector.

For example if you have a function like:

1   function test(){
2       $x = new SomeObject();
3       $y = new SomeObject();
4       $x = null;
5   }

Where SomeObject has no reference cycles.

Can you assume $x->__destruct is called at line 4 and $y->__destruct is called at line 5?

Testing the following script seems to indicate that this is true: https://gist.github.com/KAYLukas/0b1d65e57b52862f8da5

Furthermore, SplFileObject seems to work on this predicate: it is impossible to close the file, instead you just need to set the variable to null. If this would not call __destruct directly it would be impossible to open the file reliable after it has been opened with SplFileObject.

I have found that there is an assurance that the __destruct will be called eventually, just not when.

Upvotes: 0

Views: 194

Answers (1)

bwoebi
bwoebi

Reputation: 23777

Yes, you can assume that.

__destruct is always called at the moment where the last reference to the object disappears: when you can't access that object anymore in any way from the outside.

If there exist circular references, you need to wait until it circular garbage collector comes in, where it isn't defined at what point that happens.

If you have stored the object somewhere else too, you need to first remove it from there before the destructor is called.

For further information: Internal objects don't always destruct their resources upon __destruct (as the user might call it directly), but only when the object really is destroyed. (technical measure to prevent segfaults)

Also during shutdown, first variables and arrays are removed in the reverse order they were defined and where the last reference to an object disappears the object is destroyed. Then circular garbage collector comes in and removes the other objects and calls __destruct there.

The only thing which is undefined here, is the order in which the circular garbage collector removes objects and calls their __destruct function.

Upvotes: 1

Related Questions