Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP:为什么两个类实例共享相同的数据?_Php_Oop - Fatal编程技术网

PHP:为什么两个类实例共享相同的数据?

PHP:为什么两个类实例共享相同的数据?,php,oop,Php,Oop,早上好 我似乎对自己的代码是盲的,所以如果几周前写了一段代码,我想请求一些额外的帮助和建议 代码(缩短) 问题 当通过其中一个数据字段对数据进行迭代和分组时,我遇到了一个问题,即存储在两个不同数组中的两个不同类实例包含相同的数据,尽管我不知道为什么?当我使用一个额外的“克隆”时,问题就消失了,但我想了解为什么我的代码会以这种方式运行: foreach ($arrValues as $row) { ... $this->calculateStatistics($row); }

早上好

我似乎对自己的代码是盲的,所以如果几周前写了一段代码,我想请求一些额外的帮助和建议

代码(缩短)

问题

当通过其中一个数据字段对数据进行迭代和分组时,我遇到了一个问题,即存储在两个不同数组中的两个不同类实例包含相同的数据,尽管我不知道为什么?当我使用一个额外的“克隆”时,问题就消失了,但我想了解为什么我的代码会以这种方式运行:

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);
  }
}
如果需要更多代码来诊断问题的原因,请告诉我,我会添加更多代码


提前感谢您抽出时间

我承认没有详细阅读您的代码,但我想您在这方面有问题:

[…]对象变量不包含对象本身作为值[…]。它只包含一个允许对象访问器查找实际对象的对象标识符。当一个对象通过参数发送、返回或分配给另一个变量时,不同的变量[…]持有指向同一对象的标识符副本

如果要制作一个对象的两个独立副本,则需要对其进行克隆。如果不这样做,则传递的是同一个对象,对该对象的修改将对传递该对象的任何人可见。例如:

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

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

modify($obj);

echo $obj->foo; // baz

由于克隆,clone返回$collection的一个副本并将其分配给$collection2b,因为默认对象是在PHP中通过引用定义的;这就像我在上一篇评论中提到的其他评论员一样,我忘记了我在两个数组中都存储了指向$collection对象的相同指针,从而导致了重复。谢谢!非常感谢你给我指出OOP手册部分,现在我明白了。我感到困惑,因为我认为我根本没有修改$collection变量,但我完全忘记了我将指向$collection对象的指针存储在$this->arrTotals和$this->arrStatistics中,所以这就是问题的原因。
$obj = new stdClass;
$obj->foo = 'bar';

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

modify($obj);

echo $obj->foo; // baz