SitePoint Sponsor |
|
User Tag List
Results 1 to 15 of 15
Thread: emulate __destruct() in PHP4
-
Aug 15, 2005, 11:16 #1
- Join Date
- Jun 2004
- Location
- nyc
- Posts
- 63
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
emulate __destruct() in PHP4
Is there an elegant way to emulate a destructor in PHP4?
register_shutdown_function() won't work, since it doesn't get called if the object is unset() or reassigned, etc.
Any thoughts? Thanks very much.
-
Aug 15, 2005, 11:25 #2
- Join Date
- Nov 2004
- Location
- Romania
- Posts
- 848
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
if you have resources to close it is bad practice to use PHP5's __destroy function anyway, because with resources that needs to be closed explicitely (files or database connections) you need to have total control over the closing process.
Why ? Because you don't know how the garbage collector really behaves, do you ? I mean, are you really sure it executes __destroy() all the time in PHP5 ? I am not.
Another reason is that any exceptions or errors that get thrown inside a __destroy() are automatically ignored, so if there is an error in there, you will never know about it.
-
Aug 15, 2005, 11:30 #3
- Join Date
- Jun 2004
- Location
- nyc
- Posts
- 63
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Thanks - it's not for closing a resource, though. It's basically a situation where something needs to be logged, but it should only happen at the last possible second. In theory I could go through and explicitly call some kind of $object->log() method, but that would require a ton of code changes.
-
Aug 15, 2005, 11:43 #4
- Join Date
- Nov 2004
- Location
- Romania
- Posts
- 848
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
You can use the php.ini settings: auto_prepend_file and auto_append_file, which tell the PHP engine to loads the scripts automatically at the beginning and at the end of request respectivelly.
But you will have to have permissions to modify php.ini or to have .htaccess files.
-
Aug 15, 2005, 11:48 #5
- Join Date
- Jun 2004
- Location
- nyc
- Posts
- 63
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Thanks, bonefry, but that still doesn't solve the following situation:
$object = &new Object;
$object->doSomething();
$object = &new DifferentObject;
$object->doSomethingElse();
In that case, I need the first object to carry out some logic automatically when it ceases to exist due to the pointer being reassigned. Same goes for if it had been unset().
-
Aug 15, 2005, 12:00 #6
- Join Date
- Nov 2004
- Location
- Romania
- Posts
- 848
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by hennagaijin
Code:$object = &new Object; $object->doSomething(); $logger->register($object); $object = &new DifferentObject; $object->doSomethingElse(); $logger->register($object);
Code:class Logger { var $objects = array(); function register($object) { $objects[] = $object; } function logThemAll() { foreach ($objects AS $object) $object->logOnDestroy(); } }
Code:$logger->logThemAll();
-
Aug 15, 2005, 12:28 #7
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
As an alternative, you could use the Intercepting Filter pattern, which I would favour as there would be no need to 1) Change your INI file, and 2 ) Have the pre and post inclusion files, ie
PHP Code:// front controller
// ...
public function execute() {
$logger = new Logger( 'log-file.xml' );
$filter = new FilterOne( $logger, new FilterTwo( $logger, new FilterThree( $logger, $this ) ) );
$filter -> process();
}
// ...
public function process() {
// process front controller action at this point
}
// ...
PHP Code:class FilterOne implements IFilter {
private $logger;
private $filter;
public function __construct( ILogger $logger, IFilter $filter ) {
$this -> filter = $filter;
$this -> logger = $logger;
}
public function process() {
// do pre processing here
$this -> filter -> process();
// do post processing here, ie
$this -> logger -> doLog( ... );
}
}
class FilterTwo implements IFilter {
private $filter;
private $logger;
public function __construct( ILogger $logger, IFilter $filter ) {
$this -> filter = $filter;
$this -> logger = $logger;
}
public function process() {
// pre processing
$this -> filter -> process();
// post processing
$this -> logger -> doLog( ... );
}
}
class FilterThree implements ...
interface ILogger { ... }
interface IFilter {
public function __construct( ILogger $logger, IFilter $filter );
public function process();
}
-
Aug 15, 2005, 12:33 #8
- Join Date
- Nov 2004
- Location
- Romania
- Posts
- 848
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I don't think he has a front controller
-
Aug 15, 2005, 12:33 #9
- Join Date
- Jun 2004
- Location
- nyc
- Posts
- 63
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Yes, that's useful. It's a bit heavyhanded for my needs at the moment, but I'll play around with it. Really I should just upgrade to PHP5, since __destruct() does exactly what I need!
-
Aug 15, 2005, 12:42 #10
- Join Date
- Jun 2004
- Location
- nyc
- Posts
- 63
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by bonefry
The current version of my Controller, though, doesn't have any feature to handle clean up in this way. Shouldn't be too hard to implement, but I'm not sure I really need it right now.
-
Aug 15, 2005, 13:46 #11
Originally Posted by bonefry
-
Aug 15, 2005, 20:54 #12
- Join Date
- May 2005
- Location
- New Zealand
- Posts
- 69
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Have a look at the way PEAR emulates destructors. I haven't looked in detail but PEAR has them...
This is a viral sig. Copy me and help me spread
-
Aug 16, 2005, 00:38 #13
- Join Date
- Jun 2001
- Location
- In your basement
- Posts
- 1,268
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
it uses register_shutdown_function afaik...
If you really wanna use it, instantiate your class with an obsecure name then register it :/
- EricEric Coleman
We're consentratin' on fallin' apart
We were contenders, now throwin' the fight
I just wanna believe, I just wanna believe in us
-
Aug 16, 2005, 07:29 #14
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
It's a bit heavyhanded for my needs at the moment, but I'll play around with it.
PHP Code:// front controller again
// ...
public function execute() {
// your objects you want to log perhaps yes?
$filter = new Logger( $object_1, new Logger( $object_2, new Logger( $this ) ) );
$filter -> process();
// ...
}
public function process() {
// do your thing here
}
// ...
PHP Code:class Logger implements ILogger {
private $obj;
private $filter;
public function __construct( $object, ILogger $logger ) {
$this -> obj = $object;
$this -> filter = $logger;
}
public function process() {
// ... execute your object at this point, and
$this -> filter -> process();
// then do the logging here
}
private function doLog( $object ) {
// ...
// or you could abstract to allow a number of
// different loggers...
}
}
interface ILogger {
public function __construct( $object, ILogger $logger );
public function process();
}
-
Aug 16, 2005, 09:04 #15
- Join Date
- Nov 2004
- Location
- Romania
- Posts
- 848
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
dude, you think to much in patterns
Bookmarks