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

Reply via email to