Как мне клонировать ArrayIterator в 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();

У кого-нибудь есть объяснение этому поведению? Заранее спасибо.

3

Решение

Хотя у меня возникают трудности с поиском документации, которая прямо говорит об этом, внутренне ArrayIteratorприватный $storage Свойство, в котором содержится массив, должно быть ссылкой на массив, а не на сам массив, непосредственно сохраненный в объекте.

документация по clone Говорит, что

PHP 5 выполнит поверхностную копию всех свойств объекта. Любые свойства, которые являются ссылками на другие переменные, останутся ссылками.

Итак, когда вы clone ArrayIterator объект, новый клонированный объект содержит ссылку на тот же массив, что и исходный. Вот старый отчет об ошибке где это поведение называется ожидаемым поведением.

Если вы хотите скопировать текущее состояние 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() продвинуть указатель в нужную позицию. Вот подробный ответ, объясняющий, как это можно сделать.

5

Другие решения

Завершение того, что было сказано ранее, если вы пытаетесь клонировать класс, который наследуется от ArrayIteratorВы можете использовать этот метод для автоматического клонирования хранимого массива:

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

По вопросам рекламы [email protected]