是否有将PHP数组的副本复制到另一个的函数?
我已经烧过几次试图复制PHP数组。我想将对象内定义的数组复制到它之外的全局。
答案 0 :(得分:856)
在PHP中,数组是按副本分配的,而对象是通过引用分配的。这意味着:
$a = array();
$b = $a;
$b['foo'] = 42;
var_dump($a);
将屈服:
array(0) {
}
鉴于:
$a = new StdClass();
$b = $a;
$b->foo = 42;
var_dump($a);
收率:
object(stdClass)#1 (1) {
["foo"]=>
int(42)
}
你可能会对ArrayObject
这样的复杂性感到困惑,{{3}}是一个与数组完全相同的对象。然而,作为一个对象,它具有引用语义。
编辑:@AndrewLarsson在下面的评论中提出了一个观点。 PHP有一个称为“引用”的特殊功能。它们有点类似于C / C ++等语言中的指针,但并不完全相同。如果您的数组包含引用,那么当数组本身通过副本传递时,引用仍将解析为原始目标。这当然通常是理想的行为,但我认为值得一提。
答案 1 :(得分:170)
PHP将默认复制数组。 PHP中的引用必须是明确的。
$a = array(1,2);
$b = $a; // $b will be a different array
$c = &$a; // $c will be a reference to $a
答案 2 :(得分:39)
如果您有一个包含对象的数组,则需要复制该数组而不触及其内部指针,并且需要克隆所有对象(这样您在进行更改时不会修改原始数据到复制的数组),使用它。
不接触数组内部指针的技巧是确保你正在使用数组的副本,而不是原始数组(或对它的引用),所以使用函数参数将完成工作(因此,这是一个接收数组的函数)。
请注意,如果您希望克隆其属性,仍需要在对象上实施__clone()。
此函数适用于任何类型的数组(包括混合类型)。
function array_clone($array) {
return array_map(function($element) {
return ((is_array($element))
? array_clone($element)
: ((is_object($element))
? clone $element
: $element
)
);
}, $array);
}
答案 3 :(得分:28)
当你这样做时
$array_x = $array_y;
PHP复制数组,所以我不确定你会怎么被烧掉。对于你的情况,
global $foo;
$foo = $obj->bar;
应该可以正常工作。
为了被烧毁,我认为你要么必须使用引用,要么希望克隆数组中的对象。
答案 4 :(得分:17)
array_merge()
是一个可以在PHP中将一个数组复制到另一个数组的函数。
答案 5 :(得分:13)
简单并使深层复制破坏所有链接
$new=unserialize(serialize($old));
答案 6 :(得分:9)
如果阵列中只有基本类型,则可以执行此操作:
$copy = json_decode( json_encode($array), true);
您无需手动更新参考文件 我知道这对每个人都不起作用,但它对我有用
答案 7 :(得分:8)
简单而整洁的PHP> = 5.3
$cloned = array_replace([], $YOUR_ARRAY);
array_replace
(或array_replace_recursive
)。对我来说,这是最干净的方式,就像JavaScript中的Object.assign
一样。
$original = [ 'foo' => 'bar', 'fiz' => 'baz' ];
$cloned = array_replace([], $original);
$clonedWithReassignment = array_replace([], $original, ['foo' => 'changed']);
$clonedWithNewValues = array_replace([], $original, ['add' => 'new']);
$original['new'] = 'val';
将导致
// original:
{"foo":"bar","fiz":"baz","new":"val"}
// cloned:
{"foo":"bar","fiz":"baz"}
// cloned with reassignment:
{"foo":"changed","fiz":"baz"}
// cloned with new values:
{"foo":"bar","fiz":"baz","add":"new"}
答案 8 :(得分:4)
由于这个问题没有在任何答案中涵盖,现在可以在PHP 5.3中使用(假设Original Post使用的是5.2)。
为了维护数组结构并更改其值,我更倾向于使用array_replace
或array_replace_recursive
,具体取决于我的用例。
http://php.net/manual/en/function.array-replace.php
以下是使用array_replace
和array_replace_recursive
的示例,证明它能够维护索引订单并能够删除引用。
下面的代码是使用自PHP 5.4以来可用的短数组语法编写的,它将array()
替换为[]
。
http://php.net/manual/en/language.types.array.php
适用于偏移索引和名称索引数组
$o1 = new stdClass;
$a = 'd';
//This is the base array or the initial structure
$o1->ar1 = ['a', 'b', ['ca', 'cb']];
$o1->ar1[3] = & $a; //set 3rd offset to reference $a
//direct copy (not passed by reference)
$o1->ar2 = $o1->ar1; //alternatively array_replace($o1->ar1, []);
$o1->ar1[0] = 'z'; //set offset 0 of ar1 = z do not change ar2
$o1->ar1[3] = 'e'; //$a = e (changes value of 3rd offset to e in ar1 and ar2)
//copy and remove reference to 3rd offset of ar1 and change 2nd offset to a new array
$o1->ar3 = array_replace($o1->ar1, [2 => ['aa'], 3 => 'd']);
//maintain original array of the 2nd offset in ar1 and change the value at offset 0
//also remove reference of the 2nd offset
//note: offset 3 and 2 are transposed
$o1->ar4 = array_replace_recursive($o1->ar1, [3 => 'f', 2 => ['bb']]);
var_dump($o1);
输出:
["ar1"]=>
array(4) {
[0]=>
string(1) "z"
[1]=>
string(1) "b"
[2]=>
array(2) {
[0]=>
string(2) "ca"
[1]=>
string(2) "cb"
}
[3]=>
&string(1) "e"
}
["ar2"]=>
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
array(2) {
[0]=>
string(2) "ca"
[1]=>
string(2) "cb"
}
[3]=>
&string(1) "e"
}
["ar3"]=>
array(4) {
[0]=>
string(1) "z"
[1]=>
string(1) "b"
[2]=>
array(1) {
[0]=>
string(2) "aa"
}
[3]=>
string(1) "d"
}
["ar4"]=>
array(4) {
[0]=>
string(1) "z"
[1]=>
string(1) "b"
[2]=>
array(2) {
[0]=>
string(2) "bb"
[1]=>
string(2) "cb"
}
[3]=>
string(1) "f"
}
答案 9 :(得分:3)
我很久以前就知道了,但这对我有用..
$copied_array = array_slice($original_array,0,count($original_array));
答案 10 :(得分:2)
这是我在Php中复制数组的方式:
function equal_array($arr){
$ArrayObject = new ArrayObject($arr);
return $ArrayObject->getArrayCopy();
}
$test = array("aa","bb",3);
$test2 = equal_array($test);
print_r($test2);
输出:
Array
(
[0] => aa
[1] => bb
[2] => 3
)
答案 11 :(得分:1)
定义:
$copy = create_function('$a', 'return $a;');
将$ _ARRAY复制到$ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
答案 12 :(得分:1)
我找到的最安全,最便宜的方式是:
<?php
$b = array_values($a);
这对重新索引数组也有好处。
这在关联数组(哈希)上不会按预期工作,但在之前的大多数回答中都没有。
答案 13 :(得分:0)
<?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;
}
?>
答案 14 :(得分:0)
在php数组中,您只需将它们分配给其他变量即可获取该数组的副本。但首先你需要确定它的类型,无论是数组还是arrayObject或stdObject。
对于简单的php数组:
$a = array(
'data' => 10
);
$b = $a;
var_dump($b);
output:
array:1 [
"data" => 10
]
答案 15 :(得分:0)
$arr_one_copy = array_combine(array_keys($arr_one), $arr_one);
只需再发布一种解决方案;)
答案 16 :(得分:0)
创建ArrayObject的副本
<?php
// Array of available fruits
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);
$fruitsArrayObject = new ArrayObject($fruits);
$fruitsArrayObject['pears'] = 4;
// create a copy of the array
$copy = $fruitsArrayObject->getArrayCopy();
print_r($copy);
?>
来自https://www.php.net/manual/en/arrayobject.getarraycopy.php
答案 17 :(得分:-1)
private function cloneObject($mixed)
{
switch (true) {
case is_object($mixed):
return clone $mixed;
case is_array($mixed):
return array_map(array($this, __FUNCTION__), $mixed);
default:
return $mixed;
}
}
答案 18 :(得分:-1)
foreach($a as $key => $val) $b[$key] = $val ;
保留键和值。数组“ a”是数组“ b”的精确副本