ArrayObject :: offsetUnset以意外方式推进内部指针

时间:2018-04-24 11:31:01

标签: php

嘿伙计们我有以下情况

$col = new ArrayObject();

for ($i = 0; $i < 5; $i++)
{
    $objItem = new stdClass;
    $objItem->someVar = $i;
    $col->append($objItem);
}

现在我想通过offsetUnset删除一些密钥并执行以下操作

foreach($col AS $key => $objItem)
{
    if ($key == 2)
    {
        $col->offsetUnset($key);
    }
    echo $key.'\n';
}

funpart现在是意外的输出

0
1
2
4

为了更好的说明 - 如果你像

一样继续
foreach($col AS $key => $objItem)
{
    if ($key == 2)
    {
        $col->offsetUnset($key);
        continue;
    }
    echo $key.'\n';
}

输出

0
1
4

我从来没有想过它会绕过key中的3数字ArrayObject只是因为我删除了上一项 - 看起来内部指针增加了两次或类似的......

请记住,我也尝试了类似

的内容
$it = $col->getIterator();

foreach($it AS $key => $objItem)
{
    if ($key == 2)
    {
        $col->offsetUnset($key);
    }
    echo $key."\n";
}

输出相同

问题:

  

这是正常的行为,还是我忽略了一些关键的东西?

pS:正如nigel Ren指出这可能是Php, Spl, ArrayIterator的副本,我指出我正在寻找一个ArrayObject解决方案并且没有找到任何(我现在知道了) ArrayIterator问题可能是相同的) - 但我从来没有猜到那些是彼此相关的 - 在这方面我恳求不要关闭这个问题,因为它也可能对其他人有帮助

2 个答案:

答案 0 :(得分:0)

在您的代码中,它会在key后重置对象$col->offsetUnset($key);,并在重置后继续使用下一个键3->someVar值为4的元素,这就是你得到这个输出的原因。

所以你可以简单地使用另一个迭代来打印你的对象。它会起作用。

HTMLCollection

Out put

0
1
3
4

答案 1 :(得分:0)

此Bug的解决方案实际上非常简单并且已发布here 被称为Tsounabe的用户。

我在这里提出他的解决方案 - 只有一次更改 - 他指的是ArrayIterator而我正在谈论ArrayObject - 但两者都使用相同的功能getArrayCopy

foreach($col->getArrayCopy() AS $key => $objItem)
{
    if ($key == 2)
    {
        $col->offsetUnset($key);
        continue;
    }
    echo $key.'\n';
}

结论

  

为了避免这个错误,唯一令人满意的解决方案是getArrayCopy()的使用,{{1}}

下的官方PHP网站上有记录