我找到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
*/
解决方法:
这是因为通过在foreach循环内分离对象,这会阻止SplObjectStorage :: next正常工作.我可以在PHP文档中的this个用户贡献的注释中找到此信息(因此,以其实际价值为准).
If you want to detach objects during iterations, you should dereference objects, before you call next() and detach the reference after next()
也有一个关于bug的报告,显然它不起作用的原因是因为在分离时,该方法回退了容器的内部数组指针,这在循环内分离时会造成破坏.
在您的情况下,请遵循该说明,您可以像这样更改从存储容器中删除对象的循环,它应能按预期工作:
$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 ==
*/