Re: New destructors implementation
| From: | Zeev Suraski | Date: | Fri, 06 Feb 2004 19:07:16 +0000 |
| Subject: | Re: New destructors implementation | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-7633@lists.php.net to get a copy of this message | ||
At 13:01 06/02/2004, Stephane Drouard wrote:
== Quote from Red Wingate (redeye@erisx.de)'s article Is the removal of a specific order on the __destruct() calls necessary? It's a pain in the ass the be unable to predict in which order the __destruct() calls are made. I did the following test: <? class C { function __construct($n) {To make a long story short, no. Circular references are hardly the problem, even a one-sided reference can be problematic. Just one example (there are many others) - you have $container and $obj, both are global variables, $container has a reference to $obj and uses it during destruction. Voila, you have a problem - you have to somehow ensure that $obj's destructor is called only after $container's destructor. Yes, I agree it's somewhat of a pain, but that's the price of getting destructors in the first place. It may be one of the reasons destructors never made it into Java. I have to say that introducing them into PHP was most probably a mistake, but one that we'll have to live with due to popular demand. Zeev$this->n = $n;} function __destruct() {print $this->n . '-';} } for ($i = 0; $i < 10; $i++) $t[] = new C($i); $t[5]->o = $t[1]; // 5 should be deleted before 1 $t[8]->o = $t[5]; // 8 should be deleted before 5 (so 1) ?> The destruction order (0-1-2-3-4-5-6-7-8-9) does not respect the dependences. This is the current implementation. But when I execute the following: <? class C ... function f() { for ($i = 0; $i < 10; $i++)$t[] = new C($i);$t[5]->o = $t[1]; // 5 must be deleted before 1 $t[8]->o = $t[5]; // 8 must be deleted before 5 (and 1) } f(); ?> The result is '0-2-3-4-6-7-8-5-1-9', the objects are destroyed in an order that respects the dependences. If I now do a circular reference ($t[1]->o = $t[5]), these 2 objects (1 and 5) are not destroyed at the end of f(), like the others, but at the end of script (like global objects). Couldn't PHP implement global object destruction that way: * firstly try to destroyed them in the same way as for local variables (respecting dependences), * for objects that were not destroyed in the first step (certainly circular references), destroy them as currently implemented (no dependence check). A notice could also be displayed.