如何在 PHP 中克隆对象数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6418903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to clone an array of objects in PHP?
提问by DisgruntledGoat
I have an array of objects. I know that objects get assigned by "reference" and arrays by "value". But when I assign the array, each element of the array is referencing the object, so when I modify an object in either array the changes are reflected in the other.
我有一个对象数组。我知道对象由“引用”分配,数组由“值”分配。但是当我分配数组时,数组的每个元素都引用了该对象,因此当我修改任一数组中的对象时,更改会反映在另一个数组中。
Is there a simple way to clone an array, or must I loop through it to clone each object?
有没有一种简单的方法来克隆一个数组,或者我必须循环遍历它来克隆每个对象?
采纳答案by BoltClock
References to the same objects already get copied when you copy the array. But it sounds like you want to shallow-copydeep-copy the objects being referenced in the first array when you create the second array, so you get two arrays of distinct but similar objects.
复制数组时,已复制对相同对象的引用。但听起来您想在创建第二个数组时对第一个数组中引用的对象进行浅拷贝和深拷贝,因此您会得到两个不同但相似的对象数组。
The most intuitive way I can come up with right now is a loop; there may be simpler or more elegant solutions out there:
我现在能想到的最直观的方法是循环;可能有更简单或更优雅的解决方案:
$new = array();
foreach ($old as $k => $v) {
$new[$k] = clone $v;
}
回答by erani
$array = array_merge(array(), $myArray);
回答by Daniel Teichman
You need to clone objects to avoid having references to the same object.
您需要克隆对象以避免引用同一个对象。
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;
}
回答by Sébastien Fauvel
As suggested by AndreKR, using array_map() is the best way to go if you already know that your array contains objects:
正如 AndreKR 所建议的,如果您已经知道您的数组包含对象,则使用 array_map() 是最好的方法:
$clone = array_map(function ($object) { return clone $object; }, $array);
回答by hakre
I opted for clone as well. Cloning an array does not work (you could consider some arrayaccess implementation to do so for you), so as for the array clonewith array_map:
我也选择了克隆。克隆一个数组不起作用(你可以考虑一些 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);
Array clone with serialize and unserialize
带有序列化和反序列化的数组克隆
If your objects support serialisation, you can even sort of deep shallow copy/clonewith a tour into their sleeping state and back:
如果您的对象支持序列化,您甚至可以进行深浅复制/克隆,并进入它们的睡眠状态并返回:
$f = new foo('moo');
$a = array($f);
$b = unserialize(serialize($a));
$b[0]->store='bar';
var_dump($a, $b);
However, that can be a bit adventurous.
但是,这可能有点冒险。
回答by AndreKR
You need to loop it (possibly using a function like array_map()
for that), there is no PHP function to automatically perform a deep copy of an array.
您需要循环它(可能使用类似的函数array_map()
),没有 PHP 函数可以自动执行数组的深层复制。
回答by nuKs
I've done it like this:
我是这样做的:
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.
函数 arg 复制数组而不克隆对象,然后克隆每个嵌套对象。因此,如果该算法不在函数内部使用,它将不起作用。
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.
注意这个函数递归地克隆数组。如果您不希望这种情况发生,您可以使用array_walk
代替array_walk_recursive
。
回答by Trendfischer
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:
这是我对一系列对象和克隆的最佳实践。通常,为数组中使用的每个对象(或接口)类都有一个 Collection 类是一个好主意。使用魔术功能__clone
克隆成为正式的例程:
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:
要克隆您的阵列,请将其用作 Collection,然后将其克隆:
$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.
关于使用 ArrayObject 的一个重要注意事项是,您不能再使用了is_array()
。所以在重构你的代码时要注意这一点。
回答by Samer Abu Gahgah
For PHP 5 and above one can use ArrayObject
cunstructur to clone an array like the following:
对于 PHP 5 及以上版本,可以使用ArrayObject
cunstructur 来克隆如下所示的数组:
$myArray = array(1, 2, 3);
$clonedArray = new ArrayObject($myArray);
回答by Minwork
If you have multidimensional arrayor array composed of both objects and other valuesyou can use this method:
如果您有多维数组或由对象和其他值组成的数组,则可以使用此方法:
$cloned = Arr::clone($array);
from that library.
从那个图书馆。