PHP에서 객체 배열을 복제하는 방법은 무엇입니까?
개체 배열이 있습니다. 객체는 "참조"로 할당되고 배열은 "값"으로 할당된다는 것을 알고 있습니다. 그러나 배열을 할당하면 배열의 각 요소가 객체를 참조하므로 두 배열의 객체를 수정하면 변경 사항이 다른 배열에 반영됩니다.
배열을 복제하는 간단한 방법이 있습니까, 아니면 각 개체를 복제하기 위해 반복해야합니까?
동일한 객체에 대한 참조는 배열을 복사 할 때 이미 복사됩니다. 그러나 두 번째 배열을 만들 때 첫 번째 배열에서 참조되는 객체 를
얕은 복사 딥 복사
하려는 것처럼 들리
므로 별개이지만 유사한 객체의 두 배열을 얻습니다.
제가 지금 생각 해낼 수있는 가장 직관적 인 방법은 루프입니다. 더 간단하거나 더 우아한 해결책이있을 수 있습니다.
$new = array();
foreach ($old as $k => $v) {
$new[$k] = clone $v;
}
$array = array_merge(array(), $myArray);
동일한 개체에 대한 참조를 피하기 위해 개체를 복제해야합니다.
function array_copy($arr) {
$newArray = array();
foreach($arr as $key => $value) {
if(is_array($value)) $newArray[$key] = array_copy($value);
else if(is_object($value)) $newArray[$key] = clone $value;
else $newArray[$key] = $value;
}
return $newArray;
}
AndreKR이 제안한대로 array_map ()을 사용하는 것은 배열에 객체가 포함되어 있다는 것을 이미 알고있는 경우 가장 좋은 방법입니다.
$clone = array_map(function ($object) { return clone $object; }, $array);
나는 또한 클론을 선택했습니다. 배열을 복제하는 것은 일 때문에에 관해서는, (일부 arrayaccess 구현이 당신을 위해 그렇게 할 고려할 수) 않는 배열 복제 와 array_map :
class foo {
public $store;
public function __construct($store) {$this->store=$store;}
}
$f = new foo('moo');
$a = array($f);
$b = array_map(function($o) {return clone $o;}, $a);
$b[0]->store='bar';
var_dump($a, $b);
직렬화 및 직렬화 해제를 사용한 어레이 복제
객체가 직렬화를 지원하는 경우 잠자기 상태로 돌아갔다가 돌아와서 딥 얕은 복사 / 복제 를 수행 할 수도 있습니다 .
$f = new foo('moo');
$a = array($f);
$b = unserialize(serialize($a));
$b[0]->store='bar';
var_dump($a, $b);
그러나 그것은 약간 모험적 일 수 있습니다.
당신은 그것을 반복해야합니다 (아마도 array_map()
그 와 같은 함수를 사용하여 ), 배열의 깊은 복사를 자동으로 수행하는 PHP 함수는 없습니다.
다음과 같이했습니다.
function array_clone($array) {
array_walk_recursive($array, function(&$value) {
if(is_object($value)) {
$value = clone $value;
}
});
return $array;
}
The function arg copies the array without cloning the objects, then each nested object is cloned. So it won't work if the algorithm is not used inside a function.
Note this function clone the array recursively. You can use array_walk
instead of array_walk_recursive
if you do not want this to happen.
Here is my best practice on an array of objects and cloning. Usually it is a good idea, to have a Collection class for each class of objects (or interface), which are used in an array. With the magic function __clone
cloning becomes a formalized routine:
class Collection extends ArrayObject
{
public function __clone()
{
foreach ($this as $key => $property) {
$this[$key] = clone $property;
}
}
}
To clone your array, use it as Collection and then clone it:
$arrayObject = new Collection($myArray);
$clonedArrayObject = clone $arrayObject;
One step further, you should add a clone method to your class and each sub-class, too. This is important for deep cloning, or you might have unintended side effects:
class MyClass
{
public function __clone()
{
$this->propertyContainingObject = clone $this->propertyContainingObject;
}
}
An important note on using ArrayObject is, that you cannot use is_array()
any longer. So be aware of this on refactoring your code.
or also
$nuarr = json_decode(json_encode($array));
but it is expensive, I prefer Sebastien version (array_map)
Objects are passed by pointed by default and are not always easy to clone especially as they may have circular references. You would be better suited with a different choice of data structures.
For those providing solutions to shallow copy the easier way is this:
$b = (array)$a;
For deep copies I do not recommend this solution:
$nuarr = json_decode(json_encode($array));
This is for a deep copy. It only supports a subset of PHP types and will swap objects to array or arrays to objects which might not be what you want as well as potentially corrupting binary values and so on.
If you make a manual recursive function for deep copies the memory usage will be much less afterwards for scalar values and keys so using json or any serializer an impact beyond its point of execution.
It may be better to use unserialize(serialize($a)) for deep copies if performance is not a concern which has wider support for things such as objects though I would not be surprised if it breaks for circular references and several other unusual things.
array_merge_recursive or array_walk_recursive can also be used for arrays.
You can easily create your own recursive function that uses is_object and is_array to choose the appropriate means of copying.
For PHP 5 and above one can use ArrayObject
cunstructur to clone an array like the following:
$myArray = array(1, 2, 3);
$clonedArray = new ArrayObject($myArray);
If you have multidimensional array or array composed of both objects and other values you can use this method:
$cloned = Arr::clone($array);
from that library.
ReferenceURL : https://stackoverflow.com/questions/6418903/how-to-clone-an-array-of-objects-in-php
'program tip' 카테고리의 다른 글
자바에서 문자 자르기 (0) | 2020.12.27 |
---|---|
브라우저에 PHP 오류가 표시되지 않음 [Ubuntu 10.10] (0) | 2020.12.27 |
jquery sortable을 사용할 때 항목을 어떻게 복제합니까? (0) | 2020.12.27 |
모든 DataGrid 행 및 셀 테두리 제거 (0) | 2020.12.27 |
페이지가 전체 화면을 종료하는시기를 감지하는 방법은 무엇입니까? (0) | 2020.12.27 |