php php按值复制数组元素,而不是按引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1190026/
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
php copying array elements by value, not by reference
提问by oym
I have the following code:
我有以下代码:
$data['x'] = $this->x->getResults();
$data['y'] = $data['x'];
//some code here to modify $data['y']
//this causes (undesirably) $data['x] to be modified as well
I guess since all the elements of $data are themselves references, modifying $data['y'] also modifies $data['x']..which is NOT what I want. I want $data['x'] to remain the same. Is there any way to dereference the elements here so that I can copy the elements by value?
我猜因为 $data 的所有元素本身都是引用,所以修改 $data['y'] 也会修改 $data['x'] ..这不是我想要的。我希望 $data['x'] 保持不变。有什么方法可以取消引用这里的元素,以便我可以按值复制元素?
Thanks.
谢谢。
Update: $this->x->getResults(); returns an object array. So I can then do something like: $data['x'][0]->date_create ...
更新: $this->x->getResults(); 返回一个对象数组。所以我可以做这样的事情: $data['x'][0]->date_create ...
Update: my latest attempt to clone the array looks something like this:
更新:我最近克隆数组的尝试如下所示:
$data['x'] = $this->x->getResults();
$data['y'] = $data['y'];
foreach($data['x'] as $key=>$row) {
$data['y'][$key]->some_attr = clone $row->some_attr;
}
Am I way off here? I keep getting a "__clone method called on non-object" error. From reading the responses it seems like my best option is to iterate over each element and clone it (which is what I was trying to do with that code..).
我离这儿很远吗?我不断收到“对非对象调用的 __clone 方法”错误。从阅读响应来看,我最好的选择似乎是迭代每个元素并克隆它(这就是我试图用该代码做的事情......)。
UPDATE: Just solved it!: inside the foreach loop I just needed to change the line to:
更新:刚刚解决了它!:在 foreach 循环中,我只需要将行更改为:
$data['y'][$key] = clone $row;
And it works! Thanks to everyone for the help.
它有效!感谢大家的帮助。
采纳答案by zombat
You can take advantage of the fact that PHP will dereference the results of a function call.
您可以利用 PHP 将取消对函数调用结果的引用这一事实。
Here's some example code I whipped up:
这是我编写的一些示例代码:
$x = 'x';
$y = 'y';
$arr = array(&$x,&$y);
print_r($arr);
echo "<br/>";
$arr2 = $arr;
$arr2[0] = 'zzz';
print_r($arr);
print_r($arr2);
echo "<br/>";
$arr2 = array_flip(array_flip($arr));
$arr2[0] = '123';
print_r($arr);
print_r($arr2);
The results look like this:
结果如下所示:
Array ( [0] => x [1] => y ) Array ( [0] => zzz [1] => y ) Array ( [0] => zzz [1] => y ) Array ( [0] => zzz [1] => y ) Array ( [0] => 123 [1] => y )
You can see that the results of using array_flip()during the assigment of $arrto $arr2results in differences in the subsequent changes to $arr2, as the array_flip()calls forces a dereference.
您可以看到,在array_flip()对$arrto 的分配期间使用的结果会导致对$arr2的后续更改有所不同$arr2,因为array_flip()调用会强制取消引用。
It doesn't seem terribly efficient, but it might work for you if $this->x->getResults()is returning an array:
它看起来效率不高,但如果$this->x->getResults()返回一个数组,它可能对你有用:
$data['x'] = array_flip(array_flip($this->x->getResults()));
$data['y'] = $data['x'];
See this (unanswered) threadfor another example.
有关另一个示例,请参阅此(未回答的)线程。
If everything in your returned array is an object however, then the only way to copy an object is to use clone(), and you would have to iterate through $data['x']and clone each element into $data['y'].
但是,如果返回的数组中的所有内容都是对象,那么复制对象的唯一方法是使用clone(),并且您必须遍历$data['x']每个元素并将其克隆到$data['y'].
Example:
例子:
$data['x'] = $this->x->getResults();
$data['y'] = array();
foreach($data['x'] as $key => $obj) {
$data['y'][$key] = clone $obj;
}
回答by Jér?me Schneider
array_flip()won't work when array values are not strings nor integers.
I found a simple solution, however:
array_flip()当数组值不是字符串或整数时将不起作用。但是,我找到了一个简单的解决方案:
$clonedArr = (array)clone(object)$arr;
This works thanks to the properties of clone on an object.
这要归功于对象上 clone 的属性。
回答by Itay Moav -Malimovka
回答by Pascal MARTIN
If you are working with objects, you might want to take a look at clone, to create a copyof an object, instead of a reference.
如果您正在处理对象,您可能需要查看clone, 以创建对象的副本,而不是引用。
Here is a very short example :
这是一个非常简短的示例:
First, with an array, it works by value :
首先,使用数组,它按值工作:
$data['x'] = array(
'a' => 'test',
'b' => 'glop',
);
$data['y'] = $data['x'];
$data['y'][0] = 'Hello, world!';
var_dump($data['x']); // a => test : no problem with arrays
By default, with objects, it works by reference :
默认情况下,对于对象,它通过引用工作:
$data['x'] = (object)array(
'a' => 'test',
'b' => 'glop',
);
$data['y'] = $data['x'];
$data['y']->a = 'Hello, world!';
var_dump($data['x']); // a => Hello, world! : objects are by ref
But, if you clone the object, you work on a copy :
I guess this is your case ?
但是,如果您克隆该对象,您将处理一个副本:
我想这是您的情况吗?
$data['x'] = (object)array(
'a' => 'test',
'b' => 'glop',
);
$data['y'] = clone $data['x'];
$data['y']->a = 'Hello, world!';
var_dump($data['x']); // a => test : no ref, because of cloning
Hope this helps,
希望这可以帮助,
回答by Rex the Strange
I just discovered that if you simply want a copy of an array of values (no references) from a constant then you can just write:
我刚刚发现,如果你只是想要一个常量的值数组(没有引用)的副本,那么你可以只写:
$new_array = (array) (object) self::old_array;
$new_array = (array) (object) self::old_array;
Not an exact answer to the OP's question but it helped me and might help someone else.
不是 OP 问题的确切答案,但它帮助了我并且可能会帮助其他人。
回答by uKolka
You could use this function to copy multidimensional arrays containing objects.
您可以使用此函数复制包含对象的多维数组。
<?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;
}
?>

