我如何在 PHP 中克隆一个 ArrayIterator?

How do i clone an ArrayIterator in PHP?

我正在尝试克隆一个 \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 属性 其中保存数组的必须是对数组的引用,而不是数组本身直接存储在对象中。

documentation on clone 表示

PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables will remain references.

因此,当您 clone ArrayIterator 对象时,新克隆的对象包含对与原始对象相同的数组的引用。 Here is an old bug report 其中这种行为被认为是预期的行为。

如果您想复制 ArrayIterator 的当前状态,您可以考虑使用数组 returned by 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() 将指针前进到所需位置。 Here is a thorough answer explaining how that could be done.

完成前面所说的,如果你想克隆一个class,ArrayIterator继承,你可以按顺序使用这个方法自动克隆存储的数组:

public function __clone(){
    parent::__construct($this->getArrayCopy());
}