2017-08-29 1 views
-2

Ich habe Code geschrieben, der Daten aus einer cURL-Quelle liest, die sie dann verarbeitet, um Datensätze von Daten zu extrahieren.In foreach loop erstellte Instanzen sind Duplikate

Jeder Datensatz wird zu einer Instanz eines Objekts mit mehreren Variablen aus den Daten. Eine Funktion extrahiert alle Daten und gibt ein Array von Objekten zurück.

Das Problem ist, dass alle Objekte den gleichen Wert haben, der der letzte Datensatz ist, der aus den Quelldaten gelesen werden soll.

Nach einigen Tests merke ich, dass dies ein Referenzproblem ist. Daten werden von der Quelle gelesen und dann einem Objekt zugewiesen, das dann zu dem Array hinzugefügt wird. Dasselbe Objekt wird in einer Schleife wiederverwendet, die alle Datensätze in der Quelle durchläuft. Jedes Mal, wenn dieses Objekt aktualisiert wird, werden alle vorherigen Werte in den Objekten im Array ebenfalls auf den neuesten Wert zurückgesetzt, da sie weiterhin auf das Objekt verweisen, wenn es aktualisiert wird.

Wie kann ich alle Werte unabhängig machen?

function get_object_array() { 
     //reads raw data from cRUL source, returns array of objects 

     //array to hold objects 
     obj_arr = []; 

     //raw data has been split into array called $record, one element for each object 
     //loops through $record array 
      foreach ($record as $rec) { 
       //splits $rec into array of data called $data 
       //creates new object, but problem here as this object 
       //is being referenced by all values so last value 
       //changes all previous objects in array 
       $obj = new SaleItem(); 
       //populates object with record data array 
       $obj->set_data($data); 
       //add object to array 
       $obj_arr [] = $obj;  
      } 
     return $obj_arr; 
    } 

Update: Hier ist die Funktion, die Daten zu setzen:

function set_data (array $arr) { 
     global $order_num, $name, $price, $cprice, $cheapest, $category; 
     try { 
      $order_num = (int)$arr[0]; 
      $name = $arr[1]; 
      $price = (float)$arr[2]; 
      $cprice = (float)$arr[3]; 
      $cheapest = $this->$price <= $this->$cprice ? true : false; 
      $category = $arr[5]; 
      return true; 
     } 
     catch (Exception $ex) { 
      echo $ex; 
      return false; 
     } 
    } 

Update: Vollständige Codeklasse:

class SaleItem { 
    public $order_num = 12; 
    public $name = ""; 
    public $price = 3.4; 
    public $cprice = 5.6; 
    public $cheapest = true; 
    public $category = "No Category"; 

    function set_data (array $arr) { 
     try { 
      $this->order_num = (int)$arr[0]; 
      $this->name = $arr[1]; 
      $this->price = (float)$arr[2]; 
      $this->cprice = (float)$arr[3]; 
      $this->cheapest = $price <= $cprice ? true : false; 
      $this->category = $arr[5]; 
      return true; 
     } 
     catch (Exception $ex) { 
      echo $ex; 
      return false; 
     } 
    } 

    function get_data() { 
     echo $this->order_num . ' num<br/>'; 
     echo $this->name . ' name<br/>'; 
     echo $this->price . ' price<br/>'; 
     echo $this->cprice . ' cprice<br/>'; 
     echo $this->cheapest . ' cheapest<br/>'; 
     echo $this->category . ' category<br/>'; 
     echo '<br/>'; 
    } 

}//end SaleItem class 
+0

Sollte es nicht sein '$ obj-> set_data ($ rec);'? –

+0

Woher kommen '$ Daten' ??? – yivi

+0

$ Daten werden nach Weiterverarbeitung von $ rec abgeleitet. $ rec ist eine Zeichenkette mit 6 Werten und $ data ist ein Array mit diesen Werten, die aufgeteilt und von der Zeichenkette bereinigt werden. – Kwangle

Antwort

2

Sie verwenden globale Variablen anstelle von Mitgliedern. Entfernen

global $order_num, $name, $price, $cprice, $cheapest, $category; 

Von der Funktion und Vorwort jeden Auftrag mit $ this->

$this->order_num = (int)$arr[0]; 
     $this->name = $arr[1]; 
     $this->price = (float)$arr[2]; 
     $this->cprice = (float)$arr[3]; 
     $this->cheapest = $this->price <= $this->cprice; 
     $this->category = $arr[5]; 
+0

Nein, $ rec erfordert eine weitere Verarbeitung (nicht gezeigt), um es in ein Array von Werten umzuwandeln, die die Funktion set_data verwenden kann. Ich habe den Code getestet und zu diesem Zeitpunkt sind die Daten korrekt, aber es ändert sich, wenn $ Obj mit neueren Daten aktualisiert wird, wodurch alle vorherigen Werte gleich werden. Vielen Dank. – Kwangle

+0

Wir müssen SaleItem :: set_data und alle Unterfunktionen dann sehen. Wenn $ data beim Aufruf von set_data korrekt ist, liegt das Problem in der Zuweisung des Objekts. Die Einstellung von $ data wäre auch nützlich, auch wenn es sich um einen gefälschten/kommentierten Code handelt. –

+0

Bearbeitet basierend auf Ihren neuen Informationen. Sie vergeben globale Variablen, die in allen Instanzen gleich sind, anstelle von teilnehmerspezifischen Variablen. –