2009-07-27 242 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的問題的確切答案,但它幫助我,並可能幫助別人。