[RFC] Magic Method that handles unset($object)
| From: | Sebastian Bergmann | 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