我发现this comment on the PHP doc page并对此感到惊讶。
他的评论可能不是最好的,但我想知道为什么以下脚本的输出是"留在存储中:2"?为什么"输出:"没有显示" 2"。
我希望在分离所有对象后存储空为空。
<?php
class A {
public $i;
public function __construct($i) {
$this->i = $i;
}
}
$container = new \SplObjectStorage();
$container->attach(new A(1));
$container->attach(new A(2));
$container->attach(new A(3));
$container->attach(new A(4));
$container->attach(new A(5));
foreach ($container as $item) {
echo $item->i . "\n";
$container->detach($item);
}
echo "== Left in storage ==\n";
foreach ($container as $item) {
echo $item->i . "\n";
}
/* Outputs:
1
3
4
5
== Left in storage ==
2
*/
答案 0 :(得分:4)
这是因为通过detach
foreach
循环内的对象,这可以防止SplObjectStorage::next
正常工作。我能够在PHP文档的this用户贡献说明中找到这些信息(所以请考虑它的价值)。
如果要在迭代期间分离对象,则应在调用next()之前取消引用对象,并在next()之后分离引用
还有一个bug报告可用,显然它不起作用的原因是,在分离时,方法倒带容器&# 39; s内部数组指针,这是在循环内部分离时造成破坏的原因。
在您的情况下,按照该注释,您可以像这样更改从存储容器中删除对象的循环,它应该按预期工作:
$container->attach(new A(1));
$container->attach(new A(2));
$container->attach(new A(3));
$container->attach(new A(4));
$container->attach(new A(5));
$container->rewind();
while ($container->valid()) {
$item = $container->current();
echo $item->i . "\n";
$container->next();
$container->detach($item);
}
/* Outputs:
1
2
3
4
5
== Left in storage ==
*/