php копирование элементов массива по значению, а не по ссылке

У меня есть следующий код:

$data['x'] = $this->x->getResults(); $data['y'] = $data['x']; //some code here to modify $data['y'] //this causes (undesirably) $data['x] to be modified as well 

Наверное, поскольку все элементы $ data сами являются ссылками, модификация $ data ['y'] также модифицирует $ data ['x'] .., который НЕ является тем, что я хочу. Я хочу, чтобы $ data ['x'] оставался прежним. Есть ли способ разыменовать элементы здесь, чтобы я мог копировать элементы по значению?

Благодарю.

Обновить: $ this-> x-> getResults (); возвращает массив объектов. Поэтому я могу сделать что-то вроде: $ data ['x'] [0] -> date_create …

Обновление : моя последняя попытка клонировать массив выглядит примерно так:

  $data['x'] = $this->x->getResults(); $data['y'] = $data['y']; foreach($data['x'] as $key=>$row) { $data['y'][$key]->some_attr = clone $row->some_attr; } 

Неужели я здесь? Я продолжаю получать ошибку «__clone метод, вызванный не-объектной» ошибкой. Из чтения ответов кажется, что мой лучший вариант – перебирать каждый элемент и клонировать его (это то, что я пытался сделать с этим кодом ..).

UPDATE : Просто решил это !: внутри цикла foreach мне просто нужно было изменить строку:

 $data['y'][$key] = clone $row; 

И это работает! Спасибо всем за помощь.

Вы можете воспользоваться тем фактом, что PHP будет разыменовывать результаты вызова функции.

Вот пример кода, который я взбивал:

 $x = 'x'; $y = 'y'; $arr = array(&$x,&$y); print_r($arr); echo "<br/>"; $arr2 = $arr; $arr2[0] = 'zzz'; print_r($arr); print_r($arr2); echo "<br/>"; $arr2 = array_flip(array_flip($arr)); $arr2[0] = '123'; print_r($arr); print_r($arr2); 

Результаты выглядят так:

 Массив ([0] => x [1] => y)
 Массив ([0] => zzz [1] => y) Массив ([0] => zzz [1] => y)
 Массив ([0] => zzz [1] => y) Массив ([0] => 123 [1] => y) 

Вы можете видеть, что результаты использования array_flip() во время привязки $arr к $arr2 приводят к различиям в последующих изменениях в $arr2 , так как array_flip() заставляют разыменовывать.

Это не кажется очень эффективным, но это может сработать для вас, если $this->x->getResults() возвращает массив:

 $data['x'] = array_flip(array_flip($this->x->getResults())); $data['y'] = $data['x']; 

См. Эту (неотвеченную) нить для другого примера.

Если все в вашем возвращенном массиве является объектом, однако, единственный способ скопировать объект – использовать clone() , и вам придется перебирать через $data['x'] и клонировать каждый элемент в $data['y'] .

Пример:

 $data['x'] = $this->x->getResults(); $data['y'] = array(); foreach($data['x'] as $key => $obj) { $data['y'][$key] = clone $obj; } 

array_flip() не будет работать, если значения массива не являются строками или целыми числами. Однако я нашел простое решение:

 $clonedArr = (array)clone(object)$arr; 

Это работает благодаря свойствам клона на объекте.

Не просто. Читайте о клоне

НО! если ваши элементы не являются объектами, а не переменными типа refence, у вас нет проблем.

Пример для ссылочных типов:

 $v=11; $arr[]=&$v; 

Если вы работаете с объектами, вы можете захотеть взглянуть на clone , чтобы создать копию объекта вместо ссылки .

Вот очень короткий пример:

Во-первых, с массивом он работает по значению:

 $data['x'] = array( 'a' => 'test', 'b' => 'glop', ); $data['y'] = $data['x']; $data['y'][0] = 'Hello, world!'; var_dump($data['x']); // a => test : no problem with arrays 

По умолчанию, с объектами, он работает по ссылке:

 $data['x'] = (object)array( 'a' => 'test', 'b' => 'glop', ); $data['y'] = $data['x']; $data['y']->a = 'Hello, world!'; var_dump($data['x']); // a => Hello, world! : objects are by ref 

Но, если вы клонируете объект, вы работаете над копией:
Думаю, это ваше дело?

 $data['x'] = (object)array( 'a' => 'test', 'b' => 'glop', ); $data['y'] = clone $data['x']; $data['y']->a = 'Hello, world!'; var_dump($data['x']); // a => test : no ref, because of cloning 

Надеюсь это поможет,

Вы можете использовать эту функцию для копирования многомерных массивов, содержащих объекты.

 <?php function arrayCopy( array $array ) { $result = array(); foreach( $array as $key => $val ) { if( is_array( $val ) ) { $result[$key] = arrayCopy( $val ); } elseif ( is_object( $val ) ) { $result[$key] = clone $val; } else { $result[$key] = $val; } } return $result; } ?> 

Я просто обнаружил, что если вы просто хотите получить копию массива значений (без ссылок) из константы, вы можете просто написать:

$ new_array = (массив) (объект) self :: old_array;

Не точный ответ на вопрос OP, но он помог мне и помог кому-то другому.