Re: db-connections and destructors (bug?)
| From: | Erik Hjortsberg | Date: | Sun, 15 Jul 2001 17:58:57 +0000 |
| Subject: | Re: db-connections and destructors (bug?) | ||
| References: | 1 2 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-800@lists.php.net to get a copy of this message | ||
At 17:33 2001-07-15 +0000, you wrote:
azatoth@hem.passagen.se (Erik Hjortsberg) wrote in news:5.0.2.1.0.20010715175213.00a9fec0@pop.student.lu.se: My session shows: inScriptResult|i:27;!atEndResult|!atEndError| i.e. the second line in test() is never executed Now, this is nothing PEAR can fix as it's a bug/feature of php/mysql. The reason I posted it here was that PEAR supplies a mean of doing destructors through use of register_shutdown_function(). So it should be mentioned that there are some aspects you have to take in mind when writing object-destructors. My wild guess is that the PEAR DB_mysql object's destructor releases/frees the MySQL connection resource. Now, the guess is that the destructor gets called before your objects' destructor. Thus, by the time execution gets to your object, the MySQL connection handle is long gone and you're operating with a 'dead' DB object. I suppose same applies for all other DB_*. There is no defined order in which destructors get called. This means that you can't rely in your destructor on any other objects that may have their own destructors. Mind you, the PEAR destructors are not real C++-style destructors, they are essentially a hack, pseudo-destructors. They shouldn't even be called destructors, they are functions that get called when your object is about to get wiped out of the memory. With PEAR destructors, that happens at the end of the script's execution. PHP is a garbage-collected language, where an object's lifetime is undefined. An objects is destroyed when it's no longer used by anything, which may be a couple lines later or until the script dies (which is actually a potential problem with PEAR destructors: since a reference to the objects is kept outside of them, the objects never get garbage-collected during the script's execution, only at the script's shutdown... at least, this is my guess). How to correct the problem? Don't rely on register_shutdown_function. If you are so eager to save 'update' calls to your objects, you can make every object register itself in a global 'need-updating' registry. Then, at the very end of your script, you call something like $needUpdatingRegistry-> UpdateAll();, basically a method that goes thru every registered as 'need- updating' object and calls $obj->Update(); on it. After UpdateAll() is done, the script ends, begins to shutdown and that's when the DB handler is going to 'destruct', freeing the MySQL connection handle. Or maybe I'm totally wrong and on crack. LMK.Nay, you're not _completely_ wrong. :) But even though PEAR's database-objects are subclasses of PEAR they do not contain any destructors. Meaning that they never releases their resource. But, this doesn't matter as the example I provided is independant from PEAR. Of course, I can always add a DataObject::StoreAll() at the end of my scripts. I just wanted to see if I could do it through the destructors. (And save me from introducing a new way of getting errors.) /erik hjortsberg