php通过值而不是引用复制数组元素

php通过值而不是引用复制数组元素,php,arrays,codeigniter,pointers,Php,Arrays,Codeigniter,Pointers,我有以下代码: $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 我想既然$data的所有元素本身都是引用,那么修改$data['y']也会修改$data['x']……这不是我想要的。我希望$data['x

我有以下代码:

$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
我想既然$data的所有元素本身都是引用,那么修改$data['y']也会修改$data['x']……这不是我想要的。我希望$data['x']保持不变。有没有办法在这里取消对元素的引用,以便我可以按值复制元素

谢谢

更新:$this->x->getResults();返回一个对象数组。然后我可以做一些类似的事情:$data['x'][0]->date\u create

更新: 我最近一次克隆阵列的尝试如下所示:

   $data['x'] = $this->x->getResults();     
   $data['y'] = $data['y'];
   foreach($data['x'] as $key=>$row) {
       $data['y'][$key]->some_attr = clone $row->some_attr;
   }
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 ) 我离这儿远吗?我一直收到一个“\uuu克隆方法在非对象上调用”错误。从阅读响应来看,我的最佳选择似乎是迭代每个元素并克隆它(这就是我试图使用该代码所做的…)

更新:刚刚解决了它!:在foreach循环中,我只需要将行更改为:

$data['y'][$key] = clone $row;
而且它有效!谢谢大家的帮助。

不简单。 了解

但是!如果元素是非对象非参照类型变量,则没有问题

参考类型示例:

$v=11;
$arr[]=&$v;

如果您正在使用对象,您可能需要查看,以创建对象的副本,而不是引用

下面是一个非常简短的示例:

首先,对于数组,它按值工作:

$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
默认情况下,对于对象,它通过引用工作:

$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
但是,如果克隆对象,则需要处理副本:
我猜这是你的案子


希望这有帮助,

您可以利用PHP将取消对函数调用结果的引用这一事实

下面是我编写的一些示例代码:

$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);
另一个例子见

但是,如果返回的数组中的所有内容都是对象,那么复制对象的唯一方法是使用
clone()
,并且必须迭代
$data['x']
并将每个元素克隆到
$data['y']

例如:

$data['x'] = $this->x->getResults();
$data['y'] = array();
foreach($data['x'] as $key => $obj) {
    $data['y'][$key] = clone $obj;
}

可以使用此函数复制包含对象的多维数组

<?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;
}
?>

当数组值不是字符串或整数时,
array\u flip()。
然而,我找到了一个简单的解决方案:

$clonedArr = (array)clone(object)$arr;

这要归功于对象上克隆的属性。

我刚刚发现,如果您只是想从常量中复制一个值数组(无引用),那么您可以只写:

$new_array=(array)(object)self::old_array



不是OP问题的确切答案,但它帮助了我,也可能帮助了其他人。

什么是
$this->x->getResults()
返回?对象?了解
$this->x->getResults()
返回的内容非常重要……是的,我使用的是codeigniter,这是对模型(x)的调用,该模型返回数据库查询结果的对象数组,然后您必须克隆该对象数组中的每个对象。编写自己的类时,默认情况下,不会克隆内部变量引用。您必须为对象内的每个引用实现克隆函数,例如:
public function\uuu clone(){$this->widget=clone$this->widget();}
,这些引用也应该被克隆。为什么只有当元素是对象时,我才有问题?这是因为对象本身就是引用吗?在PHP中,(从版本5 IICRC开始),默认情况下所有对象都是通过引用传递的。这个答案并不完全正确。它应该是“如果你的元素不是引用,你就没有问题。”。您可以有非对象的引用。对象不是引用,它们在技术上是指针,但它们的行为看起来像引用。感谢代码示例。您知道克隆函数是否相对有效吗?我问这个问题是因为我知道在java中,如果可能的话,通常最好避免这种情况。我不知道效率如何,但是如果您需要功能性,这并不重要,不是吗?(而且,考虑到您刚才正在执行一个DB查询,与脚本的其余部分相比,它不应该那么长:-))我认为唯一内在的低效是因为您将内存量加倍,以便将同一对象存储两次。因此,它的效率与复制任何其他变量一样低。我遇到了一些问题:正如你在上一句中提到的,我返回的数组中的所有内容都是一个对象。你可以发布一些代码,说明如何迭代数组并克隆每个元素吗?我一直收到一个“\u clone method called on non object”错误。谢谢。没问题,我加了一个例子
clone
仅对实际对象有效,因此如果
$this->x->getResults()的返回结果
是一个对象数组而不是一个对象,那么你不能克隆数组,你必须分别克隆数组的每个元素。
数组\u flip
不是一个好主意!!如果您有两个具有相同值的键,那么在调用
array\u flip
函数时,第一个键将丢失。这里有一些错误信息。函数return不执行深度解引用。上面的魔法是
array\u flip(array\u flip($array))
?所以它不会递归到任何数组属性。是的,它不会。因此,我想如果有任何数组属性包含更多的对象,您可以使用
\uu clone()
让对象自己知道应该如何准确地克隆它们。这不起作用。如果
$arr
中包含引用变量,则新数组仍将包含它们。引用在克隆后仍然有效。请确认@RyanYoosefi引用变量仍然是引用。
<?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;
}
?>
$clonedArr = (array)clone(object)$arr;