ID: 30823 User updated by: richard dot quadling at bandvulc dot co dot uk Reported By: richard dot quadling at bandvulc dot co dot uk -Status: Feedback +Status: Open Bug Type: Class/Object related Operating System: Windows XP Pro SP2 PHP Version: 5.0.2 New Comment:
Nope. The output is ... destroy A destroy B Objects are destroyed in the order they are created. This is, in my opinion, bad. I would expect ... destroy B destroy A (and it took me at least 2 minutes to work out why I got nothing at all - short tags!). Richard. Previous Comments: ------------------------------------------------------------------------ [2004-11-18 22:29:44] [EMAIL PROTECTED] Please, run this code: <? class a { function __destruct() { echo "destroy A\n"; } } class b { function __destruct() { echo "destroy B\n"; } } $a = new a; $b = new b; ?> and make sure that it works as you expect. ------------------------------------------------------------------------ [2004-11-18 11:20:59] richard dot quadling at bandvulc dot co dot uk Ha. When I said ... "So this means that even the __destruct method of objLogger has been called by the shutdown process, it has not actually destroyed the object!!!!" This applies to the code WITHOUT the NULL line. The shutdown process calls the __destruct method of objects but does not destroy them. Richard. ------------------------------------------------------------------------ [2004-11-18 11:19:09] richard dot quadling at bandvulc dot co dot uk Interesting amendment. If I add $objLogger = NULL to the end of the code, I actually get an error!!! Fatal error: Call to a member function Logging() on a non-object in D:\Data\Web Sites\Quick Scripts\public_html\PHP Bug testing\Objects destroyed FIFO.php on line 29 So this means that even the __destruct method of objLogger has been called by the shutdown process, it has not actually destroyed the object!!!! Surely this is WRONG. Once the __destruct method has been executed, that's it. Gone. Done. Finito. I did think about adding code to set the objects to NULL, but with around 80 classes with many dependencies, it would make much more sense that PHP destroyed objects in reverse order to which they were created. Richard. ------------------------------------------------------------------------ [2004-11-18 11:03:43] richard dot quadling at bandvulc dot co dot uk My example code is nothing like the real one, but a fake to prove the problem. In reality, the logger is a DB connection and the __destroy, closes the log, generates an email and submits it to another system for profiling. What is happening is that we are getting log1 of the normal size and then a tiny log2 full of destruction entries. Some of these entries take the time (more DB logic and analysis) and these SHOULD be part of the main log. Richard. ------------------------------------------------------------------------ [2004-11-18 11:01:10] richard dot quadling at bandvulc dot co dot uk Description: ------------ Hi. Create Object A (a action logging class) Create Object B (a class which allows generates logging actions). As each method in B is called a log entry is made by using an IN and OUT method on A. During the shutdown, the __destroy method of A is called (which closes the log), then, the __destroy method of B is called. This method has the logging code in it. This then tries to call a destroyed object. As you cannot refer to an object until it is created, you should always destroy objects in the reverse order in which they were created. Richard. Reproduce code: --------------- <?php class A { public function __construct() { echo 'Constructing A<br />'; } public function __destruct() { echo 'Destroying A<br />'; } public function Logging($sLog) { echo date('r') . ' '. $sLog . '<br />'; } } class B { public function __construct() { $GLOBALS['objLogger']->Logging(__METHOD__ . ' ' . __FILE__ . ' ' . __LINE__); } public function __destruct() { $GLOBALS['objLogger']->Logging(__METHOD__ . ' ' . __FILE__ . ' ' . __LINE__); } public function Action() { $GLOBALS['objLogger']->Logging(__METHOD__ . ' ' . __FILE__ . ' ' . __LINE__); } } $objLogger = new A(); $objAction = new B(); $objAction->Action(); ?> Expected result: ---------------- Constructing A Thu, 18 Nov 2004 09:51:07 +0000 B::__construct D:\Data\Web Sites\Quick Scripts\public_html\PHP Bug testing\Objects destroyed FIFO.php 24 Thu, 18 Nov 2004 09:51:07 +0000 B::Action D:\Data\Web Sites\Quick Scripts\public_html\PHP Bug testing\Objects destroyed FIFO.php 34 Thu, 18 Nov 2004 09:51:07 +0000 B::__destruct D:\Data\Web Sites\Quick Scripts\public_html\PHP Bug testing\Objects destroyed FIFO.php 29 Destroying A Actual result: -------------- Constructing A Thu, 18 Nov 2004 09:51:07 +0000 B::__construct D:\Data\Web Sites\Quick Scripts\public_html\PHP Bug testing\Objects destroyed FIFO.php 24 Thu, 18 Nov 2004 09:51:07 +0000 B::Action D:\Data\Web Sites\Quick Scripts\public_html\PHP Bug testing\Objects destroyed FIFO.php 34 Destroying A Thu, 18 Nov 2004 09:51:07 +0000 B::__destruct D:\Data\Web Sites\Quick Scripts\public_html\PHP Bug testing\Objects destroyed FIFO.php 29 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=30823&edit=1