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

Php ArrayObject::offsetUnset以意外的方式推进内部指针,php,Php,嘿,伙计们,我有下面的场景 $col = new ArrayObject(); for ($i = 0; $i < 5; $i++) { $objItem = new stdClass; $objItem->someVar = $i; $col->append($objItem); } 现在最有趣的部分是意外的输出 0 1 2 4 为了更好地说明,如果您在类似的 foreach($col AS $key => $objItem) {

嘿,伙计们,我有下面的场景

$col = new ArrayObject();

for ($i = 0; $i < 5; $i++)
{
    $objItem = new stdClass;
    $objItem->someVar = $i;
    $col->append($objItem);
}
现在最有趣的部分是意外的输出

0
1
2
4
为了更好地说明,如果您在类似的

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

0
1
4
我从来没有想过它会因为我删除了前一项而绕过
数组对象中的
number
3
,看起来内部指针增加了两倍或类似的东西

记住,我也试过类似的方法

$it = $col->getIterator();

foreach($it AS $key => $objItem)
{
    if ($key == 2)
    {
        $col->offsetUnset($key);
    }
    echo $key."\n";
}
输出是相同的

问题:

这是正常的行为还是我忽略了一些重要的事情


pS:正如nigel Ren指出的,这可能是的重复,我必须指出我在这里寻找ArrayObject解决方案,但没有找到任何解决方案(我现在知道ArrayIterator问题可能是相同的)-但我从来没有想到这些是相互关联的-在这方面,我请求不要结束这个问题,因为它可能也会帮助其他人

在您的代码中,它是在
$col->offsetUnset($key)之后重置对象
并在重置后继续下一个键
3
,它将显示
->someVar
值为
4
的元素,这就是您获得此输出的原因

因此,您可以简单地使用另一个迭代来打印对象。这会奏效的

发出

0
1
3
4

这个Bug的解决方案实际上非常简单,并且已经发布了 一个叫Tsounabe的用户

我把他的解决方案放在这里-只有一个改动-他指的是
ArrayIterator
,我指的是
ArrayObject
-但两者都使用相同的函数
getArrayCopy

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

为了避免这个错误,这里唯一令人满意的解决方案是使用
getArrayCopy()
,这在官方PHP网站上的


请分享任何现场演示?检查
var\u dump($col)
您将看到,这不是问题,它按预期工作(索引从0开始,因此key==2表示数组的第三个值)@AlivetoDie我的arrayobject包含5个值-键值2是第三个元素,但在删除键值2后,我没有得到键值为3的第四个元素…可能是@NigelRen的重复项,我会检查它-但请记住,我在这里查找
arrayobject
解决方案,但没有找到任何解决方案(我现在知道ArrayIterator问题可能是相同的)-但我从来没有想到这些是相互关联的-在这方面,我恳求不要结束这个问题,因为它可能会帮助其他人。你可以像我一样分享一个实时演示吗?如果你像你那样在
偏移设置后放置
继续
,你会看到它跳过2个键使用另一个迭代打印,看起来
offsetUnset
重置
并继续下一个索引。是的,事实上这就是我所做的-但说实话,这并不能解决问题,因为我没有预料到这种行为,我认为我不应该-在一个非常复杂的场景中花了大约90分钟才发现这不是我的错误。。。
foreach($col->getArrayCopy() AS $key => $objItem)
{
    if ($key == 2)
    {
        $col->offsetUnset($key);
        continue;
    }
    echo $key.'\n';
}