是否有一个函数将PHP数组的副本复制到另一个?

时间:2009-10-07 16:11:50

标签: php arrays copy

是否有将PHP数组的副本复制到另一个的函数?

我已经烧过几次试图复制PHP数组。我想将对象内定义的数组复制到它之外的全局。

19 个答案:

答案 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_replacearray_replace_recursive,具体取决于我的用例。

http://php.net/manual/en/function.array-replace.php

以下是使用array_replacearray_replace_recursive的示例,证明它能够维护索引订单并能够删除引用。

http://ideone.com/SzlBUZ

下面的代码是使用自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”的精确副本