Я пытаюсь клонировать объект \ 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
объект, новый клонированный объект содержит ссылку на тот же массив, что и исходный. Вот старый отчет об ошибке где это поведение называется ожидаемым поведением.
Если вы хотите скопировать текущее состояние 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()
продвинуть указатель в нужную позицию. Вот подробный ответ, объясняющий, как это можно сделать.
Завершение того, что было сказано ранее, если вы пытаетесь клонировать класс, который наследуется от ArrayIterator
Вы можете использовать этот метод для автоматического клонирования хранимого массива:
public function __clone(){
parent::__construct($this->getArrayCopy());
}