我试图克隆一个\ ArrayIterator对象,但似乎克隆的对象仍然引用原始对象.
$list = new \ArrayIterator; $list->append('a'); $list->append('b'); $list2 = clone $list; $list2->append('c'); $list2->append('d'); // below result prints '4', i am expecting result '2' echo $list->count();
有人解释过这种行为吗?先感谢您.
虽然我很难找到明确说明的文档,但内部ArrayIterator
的私有$storage
属性(其中包含数组)必须是对数组的引用,而不是直接存储在对象中的数组本身.
该文档上clone
说,
PHP 5将执行所有对象属性的浅表副本.任何引用其他变量的属性都将保留引用.
因此,当您使用clone
该ArrayIterator
对象时,新克隆的对象包含对与原始对象相同的数组的引用. 这是一个旧的错误报告,其中这种行为被认为是预期的行为.
如果要复制a的当前状态ArrayIterator
,可以考虑使用返回的数组实例化新的状态getArrayCopy()
$iter = new \ArrayIterator([1,2,3,4,5]); // Copy out the array to instantiate a new one $copy = new \ArrayIterator($iter->getArrayCopy()); // Modify it $copy->append(6); var_dump($iter); // unmodified php > var_dump($iter); class ArrayIterator#1 (1) { private $storage => array(5) { [0] => int(1) [1] => int(2) [2] => int(3) [3] => int(4) [4] => int(5) } } var_dump($copy); // modified class ArrayIterator#2 (1) { private $storage => array(6) { [0] => int(1) [1] => int(2) [2] => int(3) [3] => int(4) [4] => int(5) [5] => int(6) } }
以上是一个简单的操作,只创建一个新的ArrayIterator
,当前存储的数组作为原始数组.它并不会维持当前的迭代状态.要做到这一点,您还需要调用seek()
以将指针前进到所需位置.这是一个彻底的答案,解释如何做到这一点.