Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 复制带有引用的数组;如何仅获取值_Php_Arrays_Reference - Fatal编程技术网

Php 复制带有引用的数组;如何仅获取值

Php 复制带有引用的数组;如何仅获取值,php,arrays,reference,Php,Arrays,Reference,我在处理数组和引用时遇到了一个有趣的问题。以这段代码为例: // Set everything up $testArray = array( 'a' => array(), 'b' => array() ); $saved = array(); $ref =& $testArray['b']; // Set a value via the reference $ref = array(1); // Save the current array stat

我在处理数组和引用时遇到了一个有趣的问题。以这段代码为例:

// Set everything up
$testArray = array(
    'a' => array(),
    'b' => array()
);

$saved = array();

$ref =& $testArray['b'];

// Set a value via the reference
$ref = array(1);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?

// Set another value via the reference
$ref = array(2);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?
没什么太复杂的。它生成一个数组,并引用数组中的“深度值”

当我
var\u dump($saved)
时,结果不是我所期望的!我得到:

array(2) {
  [0]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    &array(1) {
      [0]=>
      int(2)
    }
  }
  [1]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    &array(1) {
      [0]=>
      int(2)
    }
  }
}
我认为数组是按值复制的,而不是按引用复制的。为什么
[b]
在两个点上都等于
数组(2)
?如何复制数组并断开其引用

我希望结果是:

array(2) {
  [0]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    array(1) {
      [0]=>
      int(1)
    }
  }
  [1]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    array(1) {
      [0]=>
      int(2)
    }
  }
}

为什么
$ref
仍链接到
$testArray
数组的副本?我想基本上保存数组的“状态”,让引用只更新原始而不是副本。

这是预期的行为。您可以使用函数
debug\u zval\u dump()
查看索引
b
的refcounter是否为
2

// Set everything up
$testArray = array(
    'a' => array(),
    'b' => array()
);

$saved = array();

$ref =& $testArray['b'];

// Set a value via the reference
$ref = array(1);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?
debug_zval_dump($saved[0]);

// Set another value via the reference
$ref = array(2);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?
是什么让你:

array(2) refcount(3){
  ["a"]=>
  array(0) refcount(1){
  }
  ["b"]=>
  &array(1) refcount(2){
    [0]=>
    long(1) refcount(1)
  }
}

如果要避免这种行为,需要先取消设置引用并在修改之前获取一个新的引用:

// Set everything up
$testArray = array(
    'a' => array(),
    'b' => array()
);

$saved = array();

$ref =& $testArray['b'];

// Set a value via the reference
$ref = array(1);
unset($ref);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?
debug_zval_dump($saved[0]);

$ref =& $testArray['b'];
// Set another value via the reference
$ref = array(2);
unset($ref);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?

var_dump($saved);

然而,这只是理论上的东西。当然,不使用任何引用也可以更轻松地执行此操作。

您的数组包含数组的引用,如果复制数组,子数组只是引用。。。你需要一份深度副本。创建一个递归函数:

function cloneArray($array){
    $newArray = array();

    foreach($array as $key => $value){
        if(is_array($value))
            $value = cloneArray($value);

        $newArray[$key] = $value;
    }

    return $newArray;
}

这应该可以满足您的需要

问题是当我执行
$saved[]=$testArray,引用仍处于链接状态。复制数组时如何中断引用?您是指var_dump输出中的
&array
?我使用PHP5.3来测试这个。在我的输出中没有
&array
,但是在您的输出中,
[b]
的两个值是否都等于
数组(2)
?我想基本上保存数组的“状态”,并且让引用只更新原始的而不是副本。但是,对我来说,它看起来是预期的行为。我会为你找到一些文档这里必须有一种方法来复制数组并打破引用。即使我需要在它上面循环或者使用
array\u merge\u recursive
。我发现
$saved[]=array\u map(函数($a){return$a;},$testArray)将起作用。这似乎是一个更好的版本。