2009-07-27 72 views
11

我有以下代码:PHP复制阵列元件,而不是由参考

$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 

由于$所有元素我想数据本身的引用,修改$数据[“Y”]还修改$ data ['x'] ..这不是我想要的。我希望$ data ['x']保持不变。有没有什么方法可以在这里取消引用元素,以便我可以通过值复制元素?

谢谢。

更新:$ this-> x-> getResults();返回一个对象数组。所以,我就可以这样做:$数据[ 'X'] [0] - > date_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; 
    } 

我在这里?我不断收到“在非对象上调用的__clone方法”错误。从阅读答复看来,我最好的选择是遍历每个元素并克隆它(这正是我试图用该代码做的事情)。

UPDATE:只要解决了它!:foreach循环里面我只需要行更改为:

$data['y'][$key] = clone $row; 

和它的作品!感谢大家的帮助。

+0

什么是`$ this-> x-> getResults()`返回?一个东西? – 2009-07-27 19:13:27

+0

重要的是要知道`$ this-> x-> getResults()`返回什么...... – jason 2009-07-27 19:14:11

+0

是的,我使用codeigniter,因此是对模型(x)的调用,它返回数据库查询的对象数组结果 – oym 2009-07-27 19:14:16

回答

8

你可以采取的事实,即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); 

结果是这样的:

 
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) 

你可以看到,$arr$arr2导致分配新建分配FY期间使用array_flip()的结果随后对$arr2的更改有所不同,因为array_flip()呼叫强制解除引用。

这似乎不是非常有效的,但如果是$this->x->getResults()返回一个数组它可能为你工作:

$data['x'] = array_flip(array_flip($this->x->getResults())); 
$data['y'] = $data['x']; 

的另一个例子见this (unanswered) thread

如果一切您返回数组中不过是一个对象,然后复制对象的唯一方式是使用clone(),你将不得不通过$data['x']迭代,每个元素克隆到$data['y']

例子:

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

不简单。 阅读关于clone

但是!如果你的元素是不是对象不包含类型变量你没有问题。

对于引用类型

例子:

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

为什么如果元素是对象,我只有一个问题?是因为对象本身是引用吗? – oym 2009-07-27 19:17:17

2

如果您在使用对象,你可能想看看clone,创建一个对象的副本,而不是一个参考

这里是一个非常短的例如:

首先,以与阵列,它的工作原理是值:

$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 

但是,如果你克隆该对象,你的副本工作:
我想这是你的情况?

$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 

希望这有助于

0

您可以使用此功能来复制包含对象的多维数组。

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

array_flip()当数组值不是字符串或整数时不起作用。 我发现了一个简单的解决方案,但是:

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

这个工程由于克隆的属性的对象上。

0

我发现,如果你只是想从一个恒定值(无引用)的数组的副本,那么你可以这样写:

$ new_array =(阵列)(对象)自:: old_array;

不是OP的问题的确切答案,但它帮助我,并可能帮助别人。