PHP-SplObjectStorage-分离行为

我找到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 ==
*/
上一篇:在PHP中使用SPL库中的对象方法进行XML与数组的转换


下一篇:Excel 特殊分组汇总示例