PHP引用数组的深层副本 [英] Deep copy of PHP array of references
问题描述
所以$ array是一个数组,其中所有元素都是引用.
So $array is an array of which all elements are references.
我想将此数组追加到另一个名为$ results的数组中(循环),但是由于它们是引用,因此PHP复制了引用,而$ results充满了相同的元素.
I want to append this array to another array called $results (in a loop), but since they are references, PHP copies the references and $results is full of identical elements.
到目前为止,最佳的解决方案是:
So far, the best working solution is:
$results[] = unserialize(serialize($array));
我担心效率低下.有更好的方法吗?
which I fear to be incredibly inefficient. Is there a better way to do this?
推荐答案
您可以使用以下事实:函数在返回时会取消引用结果,例如,此处$array_by_myclone
仍将引用$original
($array_by_myclone[0][0] == 'foo'
),而$array_by_assignment
将具有克隆值($array_by_assignment[0][0] == 'bar'
)
You can use the fact that functions dereferences results when returning, for exemple here $array_by_myclone
will still have a reference to $original
($array_by_myclone[0][0] == 'foo'
) while $array_by_assignment
will have a cloned value ($array_by_assignment[0][0] == 'bar'
)
$original = 'foo';
$array_of_reference = array(&$original);
function myclone($value)
{
return $value;
}
$array_by_myclone = array();
$array_by_myclone[] = array_map('myclone', $array_of_reference);
$array_by_assignment = array();
$array_by_assignment[] = $array_of_reference;
$original = 'bar';
var_dump($array_by_myclone[0][0]); // foo, values were cloned
var_dump($array_by_assignment[0][0]); // bar, still a reference
我想检查说unserialize(serialize())
更快的注释是否正确,所以我使用php 5.5进行了测试,事实证明这是错误的:即使在数据集较小的情况下,使用序列化方法也较慢,并且您拥有的数据越多,获取速度就越慢.
I wanted to check if the comment saying unserialize(serialize())
was faster was right so I did the test using php 5.5, and it turns out this is wrong: using the serialization method is slower even with a small dataset, and the more data you have the slower it gets.
lepidosteus@server:~$ php -v
PHP 5.5.1-1~dotdeb.1 (cli) (built: Aug 3 2013 22:19:30)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
with Zend OPcache v7.0.2-dev, Copyright (c) 1999-2013, by Zend Technologies
lepidosteus@server:~$ php reference.php 1
myclone: 0.000010 seconds
serialize: 0.000012 seconds
lepidosteus@server:~$ php reference.php 1000000
myclone: 0.398540 seconds
serialize: 0.706631 seconds
使用的代码:
<?php
$iterations = 1000000;
if (isset($argv[1]) && is_numeric($argv[1])) {
$iterations = max(1, (int)$argv[1]);
}
$items = array();
for ($i = 0; $i < $iterations; $i++) {
$items[] = 'item number '.$i;
}
$array_of_refs = array();
foreach ($items as $k => $v) {
$array_of_refs[] = &$items[$k];
}
function myclone($value)
{
return $value;
}
$start = microtime(true);
$copy = array_map('myclone', $array_of_refs);
$time = microtime(true) - $start;
printf("%-10s %2.6f seconds\n", 'myclone:', $time);
$start = microtime(true);
$copy = unserialize(serialize($array_of_refs));
$time = microtime(true) - $start;
printf("%-10s %2.6f seconds\n", 'serialize:', $time);
这篇关于PHP引用数组的深层副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!