I seem to recall a way to configure __destruct for a class in such a way as to ensure that circular references are cleared as soon as the external object falls out of scope. However, the simple test that I built seems to indicate that this does not behave as I expected / hoped.
Is there a way to set up my classes so that PHP clears them correctly when an external object falls out of scope?
I am not looking for alternative ways of writing this code, I am looking for whether this can be done, and if so, how? I usually try to avoid these types of circular references, if possible.
class Bar { private $foo; public function __construct($foo) { $this->foo = $foo; } public function __destruct() { print "[destroying bar]\n"; unset($this->foo); } } class Foo { private $bar; public function __construct() { $this->bar = new Bar($this); } public function __destruct() { print "[destroying foo]\n"; unset($this->bar); } } function testGarbageCollection() { $foo = new Foo(); } for ( $i = 0; $i < 25; $i++ ) { echo memory_get_usage() . "\n"; testGarbageCollection(); }
The result is as follows:
60440 61504 62036 62564 63092 63620 [ destroying foo ] [ destroying bar ] [ destroying foo ] [ destroying bar ] [ destroying foo ] [ destroying bar ] [ destroying foo ] [ destroying bar ] [ destroying foo ] [ destroying bar ]
What I was hoping for:
60440 [ destorying foo ] [ destorying bar ] 60440 [ destorying foo ] [ destorying bar ] 60440 [ destorying foo ] [ destorying bar ] 60440 [ destorying foo ] [ destorying bar ] 60440 [ destorying foo ] [ destorying bar ] 60440 [ destorying foo ] [ destorying bar ]
UPDATE:
There are some great answers to this question regarding PHP> 5.3, but I chose an answer that will work with PHP <5.3 since it really applies to my project (PHP 5.2.x).
source share