I have two things to note about SplObjectStorage:
#1: A reference to the object itself is stored (not just a hash to compare against the object) and it must be removed before the object is destroyed and the destructor is executed.
#2: SplObjectStorage::rewind() MUST be called to initiate the iterator and before SplObjectStorage::current() will return an object (and I think the only way to retrieve an object?) rather than automatically starting at the first element as I expected it to, like an array for example. This assumption is based on SplObjectStorage::current() returning NULL until SplObjectStorage::rewind() is called once the objects are contained. As a note, always use REWIND before iterating through or fetching objects.
<?php
class foo {
public function __destruct() {
print("--- DESTRUCTOR FIRED!!<br />\r\n");
}
}
$bar = new foo();
$s = new SplObjectStorage();
$s->rewind();
$s->attach($bar, array('test'));
unset($bar);
print("Object has been unset<br />\r\n");
$obj = $s->current();
var_dump($obj);
print("- Note the NULL (from \$s->current())<br />\r\n");
$s->rewind();
$s->detach( $s->current() );
?>
Output:
Object has been unset
NULL - Note the NULL (from $s->current())
--- DESTRUCTOR FIRED!!