我正在尝试克隆\ 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();
有人对此行为有解释吗?提前谢谢。
答案 0 :(得分:5)
虽然我很难找到明确说明的文档,但是内部ArrayIterator
的私有$storage
属性,其中保存的数组必须是对数组的引用,而不是直接存储在数组中的数组本身对象。
PHP 5将执行所有对象属性的浅表副本。任何引用其他变量的属性都将保留引用。
因此,当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
答案 1 :(得分:0)
完成之前的说法,如果您尝试从ArrayIterator
克隆继承的类,则可以使用此方法自动克隆存储的数组:
public function __clone(){
parent::__construct($this->getArrayCopy());
}