当我遇到一个有趣的问题时,我正在弄乱数组和引用。 以以下代码为例:
// 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_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]
在两个地方都等于array(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
数组的副本? 我想基本上保存数组的"状态",并且让引用只更新原始而不是副本。
你的数组包含数组的引用,如果你复制你的数组,子数组只是引用......您需要一个深副本。创建一个递归函数:
function cloneArray($array){
$newArray = array();
foreach($array as $key => $value){
if(is_array($value))
$value = cloneArray($value);
$newArray[$key] = $value;
}
return $newArray;
}
这应该适合您的需求
这是
预期行为。您可以使用函数debug_zval_dump()
查看索引b
的引用计数器确实是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);
然而,这只是理论上的东西。当然,您可以在不使用引用的情况下更轻松地完成此操作。