Edit report at http://bugs.php.net/bug.php?id=31326&edit=1

 ID:               31326
 Comment by:       spidgorny at gmail dot com
 Reported by:      sir dot gallahad at gmail dot com
 Summary:          Object Destruction Order
 Status:           No Feedback
 Type:             Bug
 Package:          Scripting Engine problem
 Operating System: Linux
 PHP Version:      5.0.2

 New Comment:

Hi,



I wonder why it's being not addressed for such a long time. This seems
an important bug to me. Consider:

<?php



class Index {

    var $user;



    function __destruct() {

        if ($GLOBALS['i']->user === $this) {

            // update preferences in DB

        }

    }

}



$i = new Index();

?>



This works counter-intuitive and $GLOBALS['i'] is UNSET at the time the
__destruct is called. The destructor is supposed to be called BEFORE the
object itself is destroyed. Please change the order to FILO.


Previous Comments:
------------------------------------------------------------------------
[2006-08-23 17:56:45] richardkmiller at gmail dot com

This defect has affected me as well.  I like the suggestion of 

ebenblues: destroy objects in order of references pointing to 

them (lowest to highest).  The LIFO suggestion by sir dot 

gallahad would also solve my problem,

------------------------------------------------------------------------
[2005-06-09 17:09:11] ebenblues at yahoo dot com

I believe this is a bug in PHP's garbage collection. The ordering in
which __destruct methods are called can be very important when objects
contain instances of other objects as class variables. I have run into
problems because of the simple order that PHP uses to call __destruct
methods.



The order in which objects are destroyed should be determined by the
number of references left which point to the object (I believe Java does
something like this). In general, the Zend engine should use something
like the following algorithm for garbage collection:



foreach (object left to destroy) {

  if(no references point at this object) {

    call object's __destruct method

    destroy object

  }

}



The only hole in this algorithm is that an object that contains a
reference to itself will never be destroyed and cause an endless loop in
the algorithm above. These types of objects should be destroyed last.
The above algorithm can be easily modified to achieve this. Please
address this issue with PHP garbage collection. Thanks!

------------------------------------------------------------------------
[2005-03-20 18:05:49] sni...@php.net

No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.



------------------------------------------------------------------------
[2005-02-28 21:05:52] sni...@php.net

Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip



------------------------------------------------------------------------
[2004-12-28 20:27:18] sir dot gallahad at gmail dot com

Description:
------------
First of all. It's not a bug. It's a sugestion to give more stability to
the engine.

When the Zend Engine reaches the end of a script page it cleans up the
classes that have been created.

Nowadays it cleans up in the order the classes have been created.

I suggest that it would be a safer routine to destroy a class following
a heap of objects (first in last out).

It would help some nesting routines, not mentioning the memory
allocation.



Reproduce code:
---------------
<?

$ident = 0;

class Tag {

 public $aVar;

 function __construct( $pMe ) {

  global $ident;

  $this->aVar = $pMe;

  echo
str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;",$ident)."[".$this->aVar."]<br>";

  $ident++;

 }

 function __destruct() {

  global $ident;

  $ident--;

  echo
str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;",$ident)."[/".$this->aVar."]<br>";

 }

}



$v1 = new Tag("tag1");

$v2 = new Tag("tag2");

$v3 = new Tag("tag3");

echo '<br><br>';

?>



Expected result:
----------------
[tag1]

    [tag2]

        [tag3]





        [/tag3]

    [/tag2]

[/tag1]

Actual result:
--------------
[tag1]

    [tag2]

        [tag3]





        [/tag1]

    [/tag2]

[/tag3]


------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=31326&edit=1

Reply via email to