2017-08-29 9 views
-2

私は、cURLソースからデータを読み取り、それを処理してデータレコードを抽出するコードを作成しました。foreachループで作成されたインスタンスは重複しています

各レコードは、データから設定された複数の変数を持つオブジェクトのインスタンスになります。関数はすべてのデータを抽出し、オブジェクトの配列を返します。

問題は、すべてのオブジェクトがソースデータから最後に読み取られるレコードと同じ値を持つことです。

いくつかのテストの後、私はこれが参考になる問題だと認識しています。データはソースから読み込まれ、次にオブジェクトに割り当てられ、その後オブジェクトが配列に追加されます。同じオブジェクトは、ソース内のすべてのレコードを循環するループで再利用されます。このオブジェクトが更新されるたびに、配列内のオブジェクト内の以前の値はすべて、更新時にオブジェクトを参照し続けるため、常に最新の値にリセットされます。

どのようにすべての値を独立させることができますか?

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

アップデート:ここでは、データを設定する機能です。

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

アップデート:全クラスコード:

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

で各割り当てを序文? –

+0

'$ data'はどこから来ますか? – yivi

+0

$ dataは、後で処理した後、$ recから退避されます。 $ recは6つの値を含む文字列であり、$ dataはこれらの値が分割されて文字列からクリーンアップされた配列です。 – Kwangle

答えて

2

あなたはグローバル変数の代わりのメンバーを使用しています。 `;関数から

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

を削除し、それは` $ obj-> set_data($のREC)すべきではないの$ 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

いいえ、$ recは、set_data関数が使用できる値の配列に変換するには、さらに処理する必要があります(図示せず)。私はコードをテストしましたが、この時点でデータは正しいですが、$ objが新しいデータで更新されると、以前のすべての値も同じになるたびに変更されます。ありがとう。 – Kwangle

+0

次に、SaleItem :: set_dataとそれ以降のサブ関数を参照する必要があります。 set_dataの呼び出しで$ dataが正しい場合、問題はオブジェクトの割り当てにあります。 $ dataの設定は、たとえ偽装された/コメントされた参照コードであっても有用です。 –

+0

新しい情報に基づいて編集されました。メンバー固有の変数ではなく、すべてのインスタンスで同じグローバル変数を割り当てています。 –

関連する問題