[RFC] Magic Method that handles unset($object)

From: Date: Sun, 10 Dec 2006 09:57:22 +0000
Subject: [RFC] Magic Method that handles unset($object)
Groups: php.internals 
Request: Send a blank email to internals+get-26883@lists.php.net to get a copy of this message
Consider the following code: <?php class ParentC { public $children = array(); public function __construct() { print "ParentC::__construct()\n"; } public function __destruct() { print "ParentC::__destruct()\n"; } public function addChild( $child ) { $child->parentO = $this; $this->children[] = $child; } } class Child { public $parentO = null; public function __construct() { print "Child::__construct()\n"; } public function __destruct() { print "Child::__destruct()\n"; } } function setup() { $parent = new ParentC; $child = new Child; $parent->addChild( $child ); return $parent; } while( true ) { $parent = setup(); unset( $parent ); } ?> This code prints ParentC::__construct() Child::__construct() ParentC::__construct() Child::__construct() . . . instead of ParentC::__construct() Child::__construct() Child::__destruct() ParentC::__destruct() ParentC::__construct() Child::__construct() Child::__destruct() ParentC::__destruct() . . . because unset($parent) decrements the refcount from 2 to 1 as the $child object that is aggregated by the $parent object still holds a reference to its aggregating object. The infinite while() loop is used to hide the fact that the objects are destructed at interpreter shutdown. While this works, it is not desirable in the context from which this small reproducible script is extracted. A possible solution to this problem would be the introduction of yet another "magic" method. This method would be automatically called when unset() is called on an object that implements it. Unfortunately, the name __unset() is already taken. Assuming we had such a method, the following version of ParentC would behave as desired: <?php class ParentC { public $children = array(); public function __construct() { print "ParentC::__construct()\n"; } public function __destruct() { print "ParentC::__destruct()\n"; } public function __new_magic_method() { $this->children = array(); } public function addChild( $child ) { $child->parentO = $this; $this->children[] = $child; } } ?> Is there another solution to this problem (apart from explicitly unsetting the $children array on the $parent object)?And even if there is I think that this method would be usefull. -- Sebastian Bergmann http://sebastian-bergmann.de/ GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

« previous php.internals (#26883) next »