php - SplObjectStorage - 分离行为

标签 php spl

我找到了 this comment on the PHP doc page并对此感到惊讶。

他的评论可能不是最好的,但我想知道为什么以下脚本的输出是“left in the storage: 2”?以及为什么“Outputs:”没有显示为“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 正常工作。我能够在 this 中找到此信息PHP 文档中的用户贡献注释(所以请按它的值(value)去做)。

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 - SplObjectStorage - 分离行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34338106/

相关文章:

php - 在 PHP 中使用日期时间格式

php - 如何让php/ajax从mysql获取整数

php - 如何使用 RegexIterator::REPLACE 模式?

php - 如何在 Laravel 的单个查询中从多个表中选择多个列?

php - VirtualHost 在 CentOS 7 上的 Apache 2.4.6 下不工作

php - 如何将大型对象/数组序列化为 JSON

PHP 如何对 arrayObject 进行 array_unshift

php - 如何高效使用DirectoryIterator?

PHP class_exists - 出现 fatal error : Cannot redeclare clas instead?

php - 一个 HTML 表格中的多个表单