このテストが正しく構成されている場合、ストレージの破壊前にアイテムを取り外しても、アイテムがまだ取り付けられている間にストレージを破壊した場合と比較して、目に見える違いがないことが示されているようです. detach() ブロックをコメントアウトしても、check() 出力に目に見える変化はありません。
<?php
class MyStorage extends SplObjectStorage
{
public function __destruct()
{
echo "__destruct() of ";
var_dump($this);
//parent::__destruct(); // there is no SplObjectStorage::__destruct()
}
}
class Foo
{
public function __destruct()
{
echo "__destruct() of ";
var_dump($this);
}
}
function check($message)
{
global $storage, $x, $y, $z;
echo $message, ':', PHP_EOL;
echo '$storage: ', xdebug_debug_zval('storage');
echo '$x : ', xdebug_debug_zval('x');
echo '$y : ', xdebug_debug_zval('y');
echo '$z : ', xdebug_debug_zval('z');
echo PHP_EOL, PHP_EOL;
}
check("Starting environment");
$storage = new MyStorage();
check("\$storage created");
$x = new Foo();
check("\$x created");
$y = new Foo();
check("\$y created");
$z = new Foo();
check("\$z created");
$storage->attach($x);
$storage->attach($y);
$storage->attach($z);
check("Everything is attached");
// comment out this detach() block for comparison testing
$storage->detach($x);
$storage->detach($y);
$storage->detach($z);
check("Everything is detached");
// the check() output here is key for comparing with the final check() output below
$storage = null;
check("$storage destructed");
$x = null;
check("$x destructed");
$y = null;
check("$y destructed");
$z = null;
check("$z destructed");
// final check() output appears here
SplObjectStorage オブジェクトを使用するクラスで明示的なユーザーランド detach() 手順を記述したときに、自己混乱が生じたと思います。PHP バグ #63917 [1] で強調されているように見える反復の問題は、実際には唯一のバグのある問題だと思います。最初に、destruct-with-attachments シナリオのバグを疑うようになりました。
[1] -- http://bugs.php.net/bug.php?id=63917