2013-10-28 199 views
0

早上好,PHP:爲什麼兩個類實例共享相同的數據?

我似乎是codeblind爲我自己的代碼,所以我想問一些額外的眼睛和一些代碼的建議,如果寫幾周前。

守則(縮短)

class TrackingCostCollection { 
    private $available=0; 
    private $ordered=0; 
    private $differenceNumKits=0; 

    public function fill ($row) { 
    ... 
    } 

    /** 
    * @var TrackingCostCollection $collection 
    */ 
    public function merge ($collection) { 

    $this->available += $collection->available; 
    $this->ordered += $collection->ordered; 
    $this->differenceNumKits= $this->available-$this->ordered; 
    } 
} 

的問題

當迭代和由數據字段我遇到存儲內的兩個不同的兩個不同的類的實例的問題之一分組數據數組包含相同的數據,雖然我不明白爲什麼?當我使用一個額外的「克隆」的問題消失,但我想了解爲什麼我的代碼的行爲方式是這樣:

foreach ($arrValues as $row) { 
    ... 
    $this->calculateStatistics($row); 

} 


private function calculateStatistics ($row) { 
    $fieldValue= $row['country']; 
    $collection = new TrackingCostCollection(); 
    $collection->fill($row); 

    if (!isset($this->arrStatistics[$fieldValue])) { 
    $this->arrStatistics[$fieldValue] = $collection2; 
    } else { 
    /* @var TrackingCostCollection $previousCollection2 */ 
    $previousCollection = $this->arrStatistics[$fieldValue]; 
    $previousCollection->merge($collection2); 
    $this->arrStatistics[$fieldValue] = $previousCollection; 
    unset($previousCollection); 
    } 

    // using $collection instead of $collection2 will cause 
    // two array entries containing the same data 

    $collection2= clone $collection; 
    if (!isset($this->arrTotals[$fieldValue])) { 
    $this->arrTotals[$fieldValue] = $collection2; 
    } else { 
    /* @var TrackingCostCollection $previousCollection2 */ 
    $previousCollection = $this->arrTotals[$fieldValue]; 
    $previousCollection->merge($collection2); 
    $this->arrTotals[$fieldValue] = $previousCollection; 
    unset($previousCollection); 
    } 
} 

如果更多的代碼是必要的診斷問題的原因只是讓我知道我會添加更多。

非常感謝您的時間!

+1

,克隆返回$收集的副本,並將其分配給$ collection2 – demonking

+0

默認對象由PHP參考定義。 – PeeHaa

+0

使用__clone()回調來解決此問題;就像其他評論者提到的那樣 –

回答

1

我承認我沒有通過任何詳細的代碼了,但我想你是有這個問題:

[...]的對象變量不包含對象本身作爲價值[...]。它只包含一個對象標識符,它允許對象訪問器找到實際的對象。當一個對象通過參數發送,返回或分配給另一個變量時,不同的變量[...]保存標識符的副本,該標識符指向同一個對象。

http://php.net/manual/en/language.oop5.references.php

如果你想使對象的兩個獨立的副本,你需要clone它。如果你不這樣做,那麼你傳遞的是同一個對象,任何通過這個對象的人都可以看到對它的修改。例如: -

$obj = new stdClass; 
$obj->foo = 'bar'; 

function modify(stdClass $obj) { 
    $obj->foo = 'baz'; 
} 

modify($obj); 

echo $obj->foo; // baz 
因爲克隆
+0

非常感謝我指向OOP手冊部分,現在我明白了。我很困惑,因爲我認爲我根本沒有修改$ collection變量,但我完全忘記了我在$ this-> arrTotals和$ this-> arrStatistics中存儲了指向$ collection對象的指針,所以這就是導致問題。 – SaschaM78

相關問題