Help with destructor order?

From: Date: Thu, 04 Mar 2010 15:38:57 +0000
Subject: Help with destructor order?
Groups: php.pecl.dev 
Request: Send a blank email to pecl-dev+get-7070@lists.php.net to get a copy of this message
I maintain the mongo PECL extension and I'm having a problem with my destructors. I have two classes, each of which is tied to a struct (i.e., I define the create_object field for the class entry and put the struct in the zend_object_value). So, the classes look something like: ConnectionClass struct { zend_object std; /* other fields */ } connection; DBClass struct { zend_object std; zval *connection; /* other fields */ } db; When I create an instance of DBClass, I: 1. Pass it an instance of ConnectionClass 2. Set the db struct's connection field to the ConnectionClass instance 3. Increment the ConnectionClass instance's reference count This works great in most cases, but if I create a local instance of ConnectionClass and a static instance of DBClass, the order of destructors gets messed up: <?php class Foo { static $db; public function f() { $c = new ConnectionClass(); Foo::$db = new DBClass($c); } } $f = new Foo(); $f->f(); ?> ConnectionClass's struct destructor method is called before DBClass's, despite having a higher reference count. DBClass's struct destructor calls zval_ptr_dtor(&db->connection), but db->connection has already had its struct freed, which causes segfaults. I don't really know how PHP handles destroying static vs. non-static variables, so I'm not sure what's causing this, but is there any way to let PHP know that ConnectionClass instances should hang around at least as long as the DBClass instance that contains them? "Promote" them to static variables somehow? I thought reference counting would do it, but obviously not.

« previous php.pecl.dev (#7070) next »