Can I trust the PHP __destruct () method?

In PHP5, is the __destruct () method guaranteed to be called for every instance of an object? Can program exceptions prevent this?

+36
garbage-collection php
Sep 30 '08 at 3:29
source share
5 answers

The destructor is called when all references are freed or when the script exits. I assume this means the script ends correctly. I would say that critical exceptions do not guarantee that the destructor will be called.

The PHP documentation is a bit subtle, but it says Exceptions in the destructor will cause problems.

+35
Sep 30 '08 at 3:35
source share

It is also worth mentioning that in the case of a subclass that has its own destructor, the parent destructor is not automatically called.

You must explicitly call parent :: __ destruct () from a subclass of __ destruct () if the parent class does any necessary cleanup.

+41
Sep 30 '08 at 3:53
source share

In my experience, destructors will always be called in PHP 5.3, but keep in mind that if some piece of code calls exit () or a fatal error occurs, PHP will call the destructors in "any" order (I think the actual order is the order in memory or memory order reserved for objects. In practice, this order is almost always problematic). This is referred to as the โ€œshutdown sequenceโ€ in the PHP documentation.

PHP destructor documentation :

PHP 5 introduces the concept of a destructor, similar to the concept of other object-oriented languages, such as C ++. The destructor method will be called as soon as there are no other references to a specific object or in any order during the shutdown sequence.

As a result, if you have a class X that contains a reference to Y, the destructor X can be called AFTER the destructor Y has already been called. I hope the link to Y was not so important ... Officially, this is not a mistake, because it has been documented.

However, it is very difficult to get around this problem, because officially PHP does not allow you to find out if the destructor is called normally (destructors are called in the correct order), or destructors are called in "any" order, where you cannot use data from reference objects because they are already were destroyed. You could get around this lack of detection with debug_backtrace () and examine the stack. The lack of a normal stack seems to imply a "shutdown sequence" with PHP 5.3, but it is also undefined. If you have circular references, the destructors of these objects will not be called at all with PHP 5.2 or less and will be called in "any" order during the "shutdown sequence" in PHP 5.3 or higher. For circular links, there is no logically โ€œcorrectโ€ order, so โ€œanyโ€ order is good for them.

There are some exceptions (after all, this is PHP):

  • If exit() is called in another destructor, any remaining destructors will not be called ( http://php.net/manual/en/language.oop5.decon.php )
  • If a FATAL error occurs somewhere (many possible reasons, such as trying to remove an exception from any other destructor, may be one reason)

Of course, if the PHP engine encounters a segmentation error or some other internal error, then all bets are disabled.

+11
Nov 28 2018-11-11T00:
source share

There is a current circular link error that stops the destruct method, called implicitly. http://bugs.php.net/bug.php?id=33595 It should be fixed in 5.3

+10
Sep 30 '08 at 4:01
source share

Use the shutdown function if you want to make sure: register_shutdown_function ()

+8
Dec 30 '11 at 23:10
source share



All Articles