Re: db-connections and destructors (bug?)
| From: | (Oleg Rekutin) | Date: | Sun, 15 Jul 2001 17:33:31 +0000 |
| Subject: | Re: db-connections and destructors (bug?) | ||
| References: | 1 2 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-799@lists.php.net to get a copy of this message | ||
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.
- Oleg