Marcus Boerger wrote:
Hello Gareth,
__destruct will get executed during request shutdown after the
communication has been shutdown. The only way to be able to write
from within __destruct is to deinitialize it at the end of the
script and therefore before the request is being finished. To
do so you can use 'unset($object);'
But then again why call destruct on the objects after the external
modules
have been shut down? This heavily confuses people and I see no apparent
reason
to do so (then again I'm not deep into the PHP internal structure)?
I find it highly attractive to be able to save a "session"-object via my
destructor / close DB connections - you name it.
zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);
before php_call_shutdown_functions(); etc.
Can somebody enlighten me?
./regards
Florian
__destruct will get executed during request shutdown after the
communication has been shutdown. The only way to be able to write
from within __destruct is to deinitialize it at the end of the
script and therefore before the request is being finished. To
do so you can use 'unset($object);'
But then again why call destruct on the objects after the external
modules have been shut down? This heavily confuses people and I
see no apparent reason to do so (then again I'm not deep into the PHP
internal structure)? I find it highly attractive to be able to save a
"session"-object via my destructor / close DB connections - you name
it.zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);
before php_call_shutdown_functions(); etc.
This is where I was heading as well in the original mail :)
There's a huge amount of scope within __destruct() to be able to pull
off a load of tricks really nice and cleanly - even if that's just
closing db connectections or extra logging, it's still really nice.
while I'm happy to unset($object), this is rather an ugly way round what
could be quite an elegant feature. What I found really confusing though,
was the documentation on this subject. The docs state that __destruct()
is called with no parameters when the last reference to the object is
removed from memory. It's not immediatly apparent that this happens
during shutdown; I'd have guessed at just before. This meant I spent
half an hour changing things round to see if I could work out just how
it was working. Really annoying thing being that if a class has a
private variable which is itself an object of another class, and you do
something like this inside the __destruct() function:
$this->logger->logEvent("leaving class");
then not only doesn't it work, but you don't get any errors either.
However, this would give you an error:
$this->logEvent("leaving class");
At the very least, could somebody poke the docs a bit to reflect this a
bit better? (though I'd prefer the way destruct is called to be changed
;-) )
Gareth Ardron wrote:
[...]
( though I'd prefer the way destruct is called to be
changed ;-) )
For what it's worth, i'd second that.
./regards
Florian
Hello Florian,
there is no problem in calling resource destructors/terminators in your
destructors. You simply cannot output text to your pages from them. If
this is not true then we need to fix it. For example if an object of
yours holds a database connection and your destructor executes some
SQL code this must work. Open a bug report if necessary.
regards
marcus
Monday, June 28, 2004, 1:25:15 PM, you wrote:
Marcus Boerger wrote:
Hello Gareth,
__destruct will get executed during request shutdown after the
communication has been shutdown. The only way to be able to write
from within __destruct is to deinitialize it at the end of the
script and therefore before the request is being finished. To
do so you can use 'unset($object);'
But then again why call destruct on the objects after the external
modules
have been shut down? This heavily confuses people and I see no apparent
reason
to do so (then again I'm not deep into the PHP internal structure)?
I find it highly attractive to be able to save a "session"-object via my
destructor / close DB connections - you name it.
zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);
before php_call_shutdown_functions(); etc.
Can somebody enlighten me?
./regards
Florian
--
Best regards,
Marcus mailto:helly@php.net
Marcus Boerger wrote:
Hello Florian,
there is no problem in calling resource destructors/terminators in
your destructors. You simply cannot output text to your pages from
them. If this is not true then we need to fix it. For example if an
object of yours holds a database connection and your destructor
executes some SQL code this must work. Open a bug report if necessary.
Well you can output text in destructors. All other functions are also
available but might not behave the way we would expect them to.
I was wrong regarding the mysql extension - (really bad guesswork on my
part). However if I'm not wrong this time (again I might, since I have no
dev. environment with me right now to check back with the sources) the
extensions PHP_RSHUTDOWN_FUNCTION is called before object destructors are
called. That seems now to be the problem already stated in "documentation"
bug ( #27555 ). Developers might well clean up their stuff at that point in
the extension (like write the session to disk in the session ext.) expecting
the session to be "over" what leads to confusing results for people
(extension and php developers alike) when it actually isn't.
./regards
Florian
Hello Florian,
there is no problem in calling resource destructors/terminators in your
destructors. You simply cannot output text to your pages from them. If
this is not true then we need to fix it. For example if an object of
yours holds a database connection and your destructor executes some
SQL code this must work. Open a bug report if necessary.
Does the examples I gave you before not count ?
To reiterate:
<?php
// db in this sense is an already initialised database class
// basic wrappers around the mysql functions in my case.
class logger extends db {
function logEvent($msg){
// somecode here which uses the parent db class
// to write the msg to a database
}
}
class someOtherClass {
public $log;
function __destruct(){
$log->logEvent("leaving someOtherClass");
}
}
$log = new logger;
$soc = new someOtherClass;
$soc->log = $log;
?>
in this case, the __destruct() function within someOtherClass does
absolutly bugger all.
Does the examples I gave you before not count ?
Yes. It does not count.
in this case, the __destruct() function within someOtherClass does
absolutly bugger all.
You can't reference one object from another's destructor. PHP makes no
promises about the order it'll destroy your objects during
shutdown. If you require objects to be destroyed in a particular
sequence, then you need to unset() them manually.
This issue has been discussed previously. Check the archives for more
information about why this is and why "fixing" it is difficult / impossible.
-adam
--
adam@trachtenberg.com
author of o'reilly's php cookbook
avoid the holiday rush, buy your copy today!