php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61505 Wrong destructors order
Submitted: 2012-03-26 01:07 UTC Modified: 2012-03-26 05:31 UTC
From: enelar at develop-project dot ru Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.3.10 OS: Ubuntu
Private report: No CVE-ID: None
 [2012-03-26 01:07 UTC] 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 ...

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-03-26 03:52 UTC] 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 05:31 UTC] aharvey@php.net
-Status: Open +Status: Not a bug
 [2012-03-26 05:31 UTC] aharvey@php.net
Destructor order is not guaranteed to be deterministic.
 [2012-03-26 20:38 UTC] enelar at develop-project dot ru
"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."
 [2012-03-27 05:34 UTC] phpmpan at mpan dot pl
Actually in C++ construction and destruction order of global objects is not deterministic too*. If you believed it is deterministic and based your code behaviour on this belief, you have some broken code now. Also I know no modern GC language that cares about destruction order of unrelated objects. This issue is not important in object-oriented environment.
____
* The order is defined only for a single compilation unit.
  On application level it is undefined and often leads
  to errors in code written by coders unaware of this issue.
 [2012-05-26 17:28 UTC] enelar at develop-project dot ru
--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.

Yep... Its just example, why i think its wrong..
Call they '$a' and '$b'. Dont think that i am stupid like that, annoying.
I am a '$god', first of all, i created a '$sky', then '$land_under_the_sky'.
And i want, that last of all will be '$sky', not the 
'$land_under_the_sky_when_sky_isnt_exsiting'.
Now its clear?
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 12:01:31 2024 UTC