#46169 [Com]: destruct in wrong order with static object
| From: | luke at cywh dot com | Date: | Wed, 24 Sep 2008 18:36:50 +0000 |
| Subject: | #46169 [Com]: destruct in wrong order with static object | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-129232@lists.php.net to get a copy of this message | ||
ID: 46169
Comment by: luke at cywh dot com
Reported By: luke at cywh dot com
Status: Open
Bug Type: Scripting Engine problem
Operating System: Linux
PHP Version: 5.2.6
New Comment:
Just discovered it's not just static objects. If you create an object
within a function in a local variable, it destructs after the function
finishes (like it should). But if you track it in an array in the
primary classes scope, it destructs incorrectly still. Adding the
Registry in the results, you get:
C:Registry
C:class1
C:class2
C:class3
D:Registry
D:class1
D:class2
D:class3
But I would expect this:
C:Registry
C:class1
C:class2
C:class3
D:Registry
D:class3
D:class2
D:class1
or this?:
C:Registry
C:class1
C:class2
C:class3
D:class3
D:class2
D:class1
D:Registry
Grrr... I'm not even sure. There is no consistency. 5.1.6 was "wrong",
but at least it was consistently wrong.
Previous Comments:
------------------------------------------------------------------------
[2008-09-24 18:14:17] luke at cywh dot com
Description:
------------
This is related to a bug that was fixed in version 5.2.0, which you
can read about here:
http://bugs.php.net/bug.php?id=36759
Basically if you were to initiate a class, the destruct order would be
incorrect: "C1,C2,C3,D1,D2,D3". This was corrected in 5.2.0 to be
"C1,C2,C3,D3,D2,C1".
The problem, however, still persists if you create an object inside a
static object. Code to recreate this issue is included in this bug
report.
If you initiate the classes without the Registry singleton, it
destructs properly ($c1 = new class1()...).
Testing this with 5.1.6, the destruct order is incorrect in both
situations (as i'd expect). If you unset the objects in reverse order
as they were created, both work correctly on 5.1.6 and 5.2.6.
So a work-around for either version is to simply track the objects and
unset them. But if you don't do this, the destruct order is still
incorrect if creating your objects through a singleton object.
Reproduce code:
---------------
class shorten {
public function __construct() { print 'C:' . get_class($this) . "<br
/>"; }
public function __destruct() { print 'D:' . get_class($this) . "<br
/>"; }
}
class class1 extends shorten {}
class class2 extends shorten {}
class class3 extends shorten {}
class Registry {
static private $instance = null;
private $registered = array();
static public function instance() {
if(self::$instance == null) self::$instance = new Registry();
return self::$instance;
}
private function __call($name, $arguments) {
if( ! isset($this->registered[$name]) ) $this->registered[$name] =
new $name();
return $this->registered[$name];
}
private function __get($name) {
if( ! isset($this->registered[$name]) ) $this->registered[$name] =
new $name();
return $this->registered[$name];
}
}
Registry::instance()->class1();
Registry::instance()->class2();
Registry::instance()->class3();
Expected result:
----------------
C:class1
C:class2
C:class3
D:class3
D:class2
D:class1
Actual result:
--------------
C:class1
C:class2
C:class3
D:class1
D:class2
D:class3
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=46169&edit=1