PHP에서 객체 배열을 복제하는 방법은?
저는 여러 가지 물건을 가지고 있습니다.객체는 "참조"로, 배열은 "값"으로 할당된다는 것을 알고 있습니다.그러나 배열을 할당하면 배열의 각 요소가 개체를 참조하므로, 어느 하나의 배열에 있는 개체를 수정하면 변경 사항이 다른 하나에 반영됩니다.
어레이를 복제하는 간단한 방법이 있습니까? 아니면 각 개체를 복제하려면 이를 루프로 통과해야 합니까?
$array = array_merge(array(), $myArray);
배열을 복사하면 동일한 개체에 대한 참조가 이미 복사됩니다.하지만 당신은 당신이 원하는 것처럼 들립니다.
천박한 두 번째 배열을 만들 때 첫 번째 배열에서 참조되는 개체를 심층 복사하면 서로 다르지만 유사한 개체의 배열을 두 개 얻을 수 있습니다.
제가 지금 생각해 낼 수 있는 가장 직관적인 방법은 루프입니다. 더 단순하거나 더 우아한 솔루션이 있을 수도 있습니다.
$new = array();
foreach ($old as $k => $v) {
$new[$k] = clone $v;
}
개체를 복제해야 동일한 개체에 대한 참조가 발생하지 않습니다.
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);
저도 클론을 선택했습니다.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);
직렬화 및 비직렬화를 사용한 어레이 클론
개체가 직렬화를 지원하는 경우에는 sleep 상태로 이동한 후 다음과 같이 심층 복사/클론을 수행할 수도 있습니다.
$f = new foo('moo');
$a = array($f);
$b = unserialize(serialize($a));
$b[0]->store='bar';
var_dump($a, $b);
하지만, 그것은 약간 모험적일 수 있습니다.
순수 PHP 7.4 >= 솔루션:
$cloned = array_map(fn ($o) => clone $o, $original);
해야 를 합니다 과 합니다 를 를 해야 과 등의 함수를 사용하여 루프array_map()
이 경우) 배열의 딥 카피를 자동으로 수행하는 PHP 기능은 없습니다.
저는 이렇게 해왔습니다.
function array_clone($array) {
array_walk_recursive($array, function(&$value) {
if(is_object($value)) {
$value = clone $value;
}
});
return $array;
}
function arg는 개체를 복제하지 않고 어레이를 복사한 다음 중첩된 각 개체를 복제합니다.따라서 알고리즘을 함수 내부에서 사용하지 않으면 작동하지 않습니다.
이 함수는 배열을 재귀적으로 복제합니다.능을 사용할 수 .array_walk
에 대신에array_walk_recursive
이런 일이 일어나지 않기를 바란다면요
여기에 여러 개체와 복제에 대한 저의 모범 사례가 있습니다.일반적으로 각 클래스의 객체(또는 인터페이스)에 대한 Collection 클래스를 갖는 것이 좋습니다. 이 클래스는 배열에 사용됩니다. 기능으로__clone
클로닝은 공식화된 루틴이 됩니다.
class Collection extends ArrayObject
{
public function __clone()
{
foreach ($this as $key => $property) {
$this[$key] = clone $property;
}
}
}
어레이를 복제하려면 Collection(수집)으로 사용한 다음 복제합니다.
$arrayObject = new Collection($myArray);
$clonedArrayObject = clone $arrayObject;
한 단계 더 나아가 클래스와 각 하위 클래스에도 클론 메서드를 추가해야 합니다.이는 심층 클로닝에 중요하며, 그렇지 않으면 의도하지 않은 부작용이 발생할 수 있습니다.
class MyClass
{
public function __clone()
{
$this->propertyContainingObject = clone $this->propertyContainingObject;
}
}
할 때 한 점은 ArrayObject를 사용할 수 is_array()
시 주의해야 .코드 리팩터링 시 주의하시기 바랍니다.
아니면
$nuarr = json_decode(json_encode($array));
하지만 비싸요, 저는 세바스티앙 버전(array_map)을 선호합니다.
개체는 기본적으로 가리키는 방향으로 전달되며 특히 원형 참조를 가질 수 있기 때문에 복제가 항상 쉽지는 않습니다.다양한 데이터 구조를 선택하는 것이 더 적합할 것입니다.
얕은 복사를 위한 솔루션을 제공하는 사용자에게 더 쉬운 방법은 다음과 같습니다.
$b = (array)$a;
심층 복사의 경우 이 솔루션을 권장하지 않습니다.
$nuar = json_parray(json_parray));
이것은 깊은 사본을 위한 것입니다.PHP 유형의 하위 집합만 지원하며 개체를 배열 또는 배열로 전환하여 이진 값을 손상시킬 수도 있습니다.
딥 복사본에 대한 수동 재귀 함수를 만들면 스칼라 값과 키에 대한 메모리 사용량이 이후 훨씬 적으므로 json이나 직렬화기를 사용하면 실행 지점 이상의 영향을 받을 수 있습니다.
성능이 개체와 같은 것에 더 광범위하게 지원되는 문제가 아닌 경우 심층 복사본에 대해 unserialize($a)를 사용하는 것이 더 나을 수 있습니다. 원형 참조 및 기타 특이한 것에 대해 깨져도 놀라지 않을 것입니다.
array_match_match 또는 array_walk_match를 배열에 사용할 수도 있습니다.
is_object와 is_array를 사용하여 적절한 복사 수단을 선택하는 자신만의 재귀 함수를 쉽게 만들 수 있습니다.
5은 PHP 5 의 할 을 사용할 수 있습니다.ArrayObject
다음과 같은 배열을 복제하려면 cunstructur를 사용합니다.
$myArray = array(1, 2, 3);
$clonedArray = new ArrayObject($myArray);
객체와 다른 값으로 구성된 다차원 배열 또는 배열이 있는 경우 이 방법을 사용할 수 있습니다.
$cloned = Arr::clone($array);
그 도서관에서.
이 기능을 모든 수업에 포함시키기만 하면 됩니다.개체 자체 내에 개체 배열이 있는 경우 모든 개체의 심층 복제가 수행됩니다.든을할다l다은을 트리거합니다.__clone()
다음 클래스의 함수:
/**
* Clone the object and its properties
*/
public function __clone()
{
foreach ($this as $key => $property)
{
if(is_array($property))
{
foreach ($property as $i => $o)
{
if(is_object($o)) $this->$key[$i] = clone $o;
else $this->$key[$i] = $o;
}
}
else if(is_object($property)) $this->$key = clone $property;
else $this->$key = $property;
}
}
$a = ['a'=>'A','b'=>'B','c'=>'C'];
$b = $a+[];
$a['a'] = 'AA'; // modifying array $a
var_export($a);
var_export($b);
결과:
array ( 'a' => 'AA', 'b' => 'B', 'c' => 'C', )
array ( 'a' => 'A', 'b' => 'B', 'c' => 'C', )
나는 재귀적 방법을 선호합니다.
function deepClone(mixed $object): mixed
{
switch (gettype($object)) {
case 'object':
return clone $object;
case 'array':
$ret = [];
foreach ($object as $key => $item) {
$ret[$key] = deepClone($item);
}
return $ret;
default:
return $object;
}
}
deepClone($array);
언급URL : https://stackoverflow.com/questions/6418903/how-to-clone-an-array-of-objects-in-php
'source' 카테고리의 다른 글
쿼리 실행 방법선택기All and getElementsBy* 메서드가 반환됩니까? (0) | 2023.09.06 |
---|---|
수행 표시줄에 뒤로 단추 표시 (0) | 2023.09.06 |
ajax 문제 - firebug에서는 200 OK이지만 응답 본문이 없는 빨간색 (0) | 2023.09.06 |
pcap 구조 pcap_drlen vs caplen (0) | 2023.09.06 |
사용자 지정 개체의 각 Note Property를 반복 실행 (0) | 2023.09.06 |