Edit report at https://bugs.php.net/bug.php?id=61505&edit=1
ID: 61505 Comment by: enelar at develop-project dot ru Reported by: enelar at develop-project dot ru Summary: Wrong destructors order Status: Not a bug Type: Bug Package: Class/Object related Operating System: Ubuntu PHP Version: 5.3.10 Block user comment: N Private report: N New Comment: "Destructor order is not guaranteed to be deterministic." Could you please add that in documentation? And one more "Destructors in php not like other destructors in the world. Its just laggy coded duct tape, for OOP label on language. Dont use them in C++ style, its wrong." Previous Comments: ------------------------------------------------------------------------ [2012-03-26 05:31:27] ahar...@php.net Destructor order is not guaranteed to be deterministic. ------------------------------------------------------------------------ [2012-03-26 03:52:58] phpmpan at mpan dot pl This is not related to bug36759. 36759 is about destroying referenced object before referencing one even when circular dependency is not present. Your case is completly different, as `$world` and `$human` do not reference each other. They're independent objects. `$human` is NOT part of `$world` just because you named the variables like that. Hence there is no reason to think that there should be any particular order of destruction. ------------------------------------------------------------------------ [2012-03-26 01:07:43] enelar at develop-project dot ru Description: ------------ followed: https://bugs.php.net/bug.php?id=36759 They told that fixed in 5.2*, but its wrong! Reprodused in 5.3.2 Destructors on allocated objects should be called in reverse order: $a = new world(); $b = new human(); == Shold be called as: world->__construct(); human->__construct(); human->__destruct(); world->__destruct(); == Now its calling as: world->__construct(); human->__construct(); world->__destruct(); // now people, cars and other exists without world. wtf?? human->__destruct(); == Why i think current way its wrong: When we creating object $b, we expecting that object $a exists. And while lifetime $b, object $a should be exist. Even $b dying, $a should be exists. We expect in $a that $b may be not exist, but we should`t check in all methods of $b 'is $a exist'. Destructor its not exception and should be executed right. == Some simular reports: https://bugs.php.net/bug.php?id=38572 https://bugs.php.net/bug.php?id=29032 (if we imagine that $SESSION = new bla_bla(), before our code) Test script: --------------- class screen { public $screen; public function __construct() { echo "screen construct<br>"; $text->screen = ""; } public function Write( $text ) { echo "writed to screen $text<br>"; $this->screen .= $text; } public function __destruct() { echo "screen destruct<br>"; echo $this->screen; } } $A = new screen(); class dummy { public function __constuct() { echo "dummy constuct<br>"; } public function __destuct() { echo "dummy destruct<br>"; global $A; $A->Write("Dummy: I`m dying!<br>"); // or $A->DoVeryImportantActionBeforeDie($bla, $bla1); } } $B = new dummy(); Expected result: ---------------- screen construct dummy constuct writed to screen Dummy: I`m dying! screen destruct Dummy: I`m dying! Actual result: -------------- screen construct dummy constuct screen destruct Fatal error: Call to a member function Write() on a non-object in ... ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=61505&edit=1