gpt4 book ai didi

php - ArrayObject 不允许我在遍历它时取消设置值

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:05:58 25 4
gpt4 key购买 nike

我收到了这条通知:

ArrayIterator::next(): Array was modified outside object and internal position is no longer valid in /var/www...

由这段代码在 foreach 循环的开始处生成。与通知一起,foreach 循环再次开始迭代。换句话说,每当这件事发生时,内部位置就会被重置。但根据 php 手册,ArrayObject 默认使用 ArrayIterator。

关于 ArrayIterator 手册是这样说的

This iterator allows to unset and modify values and keys while iterating over Arrays and Objects.

我是不是漏掉了什么?我发现了一些关于 ArratIterator 的错误报告,但不是这种。是 bug 还是我的问题?

version: PHP Version 5.3.10-1ubuntu3.4

<?php
//file 1:
// no namespace
abstract class holder extends \ArrayObject{
// abstract function init();

public function __construct($init){
parent::__construct($init, 1);
}
}?>

<?php
//file 2:
namespace troops;
class holder extends \holder{
public function __construct(){
parent::__construct($this->init());
}

private function init(){
return array( /*... some data from db ...*/ );
}

public function saveData(){
foreach($this as $k => $v){
$this->save($v);
if($v->number_of_items==0) {
unset($k);
// $this->offsetUnset($k); // tryed both
}
}
}
}
?>

最佳答案

ArrayObject工具 IteratorAggregate这意味着它有一个名为 getIterator() 的方法它返回一个迭代器。

php 的 foreach 循环会通过调用 getIterator() 方法自动获取迭代器,让您获取迭代器进行迭代。这很方便,但是您需要获得对此迭代器的引用才能调用 offsetUnset()迭代器本身的方法。这里的关键是您必须调用 iterators offsetUnset() 方法,而不是 ArrayObjects offsetUnset() 方法。

$ao = new ArrayObject();
$ao[] = 9;
$iter = $ao->getIterator();

foreach ($iter as $k => $v)
$iter->offsetUnset($k); // no error

迭代器正在迭代的底层 ArrayObject 发生变化,因此如果您同时在同一个 Arrayobject 上有多个事件迭代器,您仍然会遇到相同的错误。

这样做的理由很可能是迭代器可以节省内存,而不必复制底层的 ArrayObject,因为复制是处理决定当前迭代器位置应该是什么的复杂性的唯一简单解决方案。被添加到底层数组或从底层数组中删除。

关于php - ArrayObject 不允许我在遍历它时取消设置值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14151727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com