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.
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.
To do this >right< you'd need notification, not just that unset() was called on the object, but what the current state of *both* of its relevant reference counts are.
class foo {
public function __delref($objectstore_refcount, $zval_refcount)
{
if ($objectstore_refcount == 1) {
/* Only one zval is pointing to this object,
* e.g. the one used/shared by the child's backreference */
if ($zval_refcount == 1) {
/* Only one variable is pointing to this zval,
* the child's backreference property */
$this->children = array();
}
}
}
}
Of course, that assumes you only have one child. Once you introduce multiple children, they'll *probably share one object store reference through a common zval with multiple references, so you *could* do:
class foo {
public function __delref($objectstore_refcount, $zval_refcount)
{
if ($objectstore_refcount == 1) {
/* Only one zval is pointing to this object,
* e.g. the one used/shared by the child's backreference */
if ($zval_refcount == count($this->children)) {
/* Only one children's properties are pointing to this zval */
$this->children = array();
}
}
}
}
But that doesn't cover the (quite common) case where there are multiple object store references spread out among the children (and possibly other variables not contained in the object itself). Unfortunately you *can't* aggregate the total number of variable->zval->object references ince at this point in runtime, only the zval being dereferenced is known for certain.
By the way, this is part of the reason why PHP doesn't have delete().
-Sara