2009-06-28 15 views
0

次のようにだから私は、アイテム・クラスを持っている:PHPオブジェクト拡張質問

 

class Item 
{ 
    private $db; 
    private $data = array(
     'AltItem1' => null, 
     'AltItem2' => null, 
     'BaseUOM' => null, 
     'Category1' => null, 
     'Category2' => null, 
     'Category3' => null, 
     'Category4' => null, 
     'Iden' => null, 
     'IsHCS' => null, 
     'ItemDesc' => null, 
     'ItemNmbr' => null, 
     'ItemType' => null, 
     'MSDS' => null, 
     'NoteText' => null, 
     'NonStock' => null, 
     'PrcLevel' => null, 
     'TipPrice' => null, 
     'DTM_UpdType' => null, 
     'DTM_UpdDateTime' => null, 
     'DTM_DownloadDateTime' => null, 
     'DTM_UploadDateTime' => null 
    ); 

    public function __construct(mysqli $db, $id = null){ 
     $this->db = $db; 

     if(!empty($id)){ 
      $id = (int)$id; 
      $this->populate($id); 
     } 
    } 

    public function __get($key) 
    { 
     if(array_key_exists($key, $this->data)){ 
      return $this->data[$key]; 
     } 
     error_log("Invalid key '$key'"); 
     return null; 
    } 

    public function __set($key, $value) 
    { 
     if(array_key_exists($key, $this->data)){ 
      $this->data[$key] = $value; 
      return true; 
     } 
     return false; 
    } 

    public function populate($id) 
    { 
     $sql = sprintf(
      "SELECT %s FROM ItemMaster WHERE id = ?", 
      implode(", ", array_keys($this->data)) 
     ); 

     $stmt = $this->db->stmt_init(); 
     $stmt->prepare($sql) or die ("Could not prepare statement:" . $stmt->error); 
     $stmt->bind_param('i', $id); 
     $stmt->execute() or die('exec'); 
     $stmt->store_result(); 
     if($stmt->num_rows == 1) 
     { 
      $params = array(); 
      foreach($this->data as $key => $val){ 
       $params[] = &$this->data[$key]; 
      } 

      call_user_func_array(array($stmt, 'bind_result'), $params); 
      $stmt->fetch(); 
      $return = true; 
     } 
     else{ 
      user_error("No rows returned for id '$id'"); 
      $return = false; 
     } 
     return $return; 
    } 
    public function insert() 
    { 
     $params = $this->data; 
     $values = array(); 

     foreach($params as $param){ 
      $values[] = "?"; 
     } 

     $sql = sprintf(
      "INSERT INTO recurrence (%s) VALUES (%s)", 
      implode(", ", array_keys($params)), 
      implode(", ", $values) 
     ); 

     $stmt = $this->db->stmt_init(); 
     $stmt->prepare($sql) or die ("Could not prepare statement:" . $stmt->error); 

     $types = str_repeat("s", count($params)); 
     array_unshift($params, $types); 
     call_user_func_array(array($stmt, "bind_param"), $params); 

     $stmt->execute(); 

     $stmt->store_result(); 
     $result = $stmt->result_metadata(); 
    } 
    public function update() 
    { 
     $sql = "UPDATE recurrence SET "; 
     $params = array(); 
     foreach($this->data as $key => $value){ 
      $params[] = "$key = ?"; 
     } 
     $sql .= implode(", ", $params) . " WHERE id = ?"; 

     $stmt = $this->db->stmt_init(); 
     $stmt->prepare($sql) or die ("Could not prepare statement:" . $stmt->error); 

     $params = $this->data; 
     $params[] = $this->data['id']; 
     $types = str_repeat("s", count($params)); 
     array_unshift($params, $types); 
     call_user_func_array(array($stmt, "bind_param"), $params); 

     $stmt->execute(); 

     $stmt->store_result(); 
     $result = $stmt->result_metadata(); 
    } 

    } 

私の質問は、データ構造で、私はそれを持っている方法を、このクラスを拡張するための最良の方法だろう何ですか?私は基本的に買い物カゴの中にあるアイテムのために別のクラスを欲しいです。だからいくつかの余分なフィールドは数量、カートIDなどですか?クラスを拡張せずにこれを行うには良い方法がありますか?

別の言い方をすれば、別の変数$ priceがデータベースに直接格納されていないとします。だから私はそれを公開変数にしますが、それにアクセスするためのヘルパーメソッドを作成する必要があります。その場合、$ data配列はこのタイプのアイテムの最高の解決策ですか?

ありがとうございます。

答えて

1

私はあなたがやっているかもしれない民間$data変数の使用法の種類は100%わからないので、ここで私の傾向が若干異なるアプローチを取ることであろう。

代わりにオブジェクトの単一プライベート変数内のすべてのデータフィールドをグループ化する、私はプライベート変数自体、各フィールドになるだろうが、すなわち:

class Item 
{ 
    private $db; 
    private $AltItem1; 
    private $AltItem2; 
... 
etc. 

これはすぐに公に利用可能なデータを持って、あなたの問題を解決するだろうフィールドを宣言することもできます。パブリックメンバーはゲッターとセッターを必要としないので、それについて心配する必要はありません。$this->price(内部で)または$item->price(外部から)にアクセスできます。いくつかのコードを保存します。そして、populate()関数を新しいプロパティをすべて設定するための素早い変更があります。$this->data[$key]の代わりに$this->$$keyを設定するだけです。

__set()__get()を使用すると、オブジェクトの外側からでも$data専用のメンバーにアクセスしたいと思われます。それぞれのフィールドが別々に宣言されているので、それを続行できない理由はありません。 __set()__get()はまったく同じように動作します、あなただけのすなわち、微調整を必要とするだろう:あなたはすべてのフィールドを再宣言する必要はありませんので、最終的なボーナスとして

public function __get($varname) 
{ 
    if ($this->$varname !== null) return $this->varname; 
    error_log("Invalid key '$key'"); 
    return null; 
} 

を、クラスを拡張することは、容易になります$dataプロパティをオーバーライドする場合は、その全体を子供の新しいフィールドを新しいプライベートメンバーとして追加するだけです。

あなたの人生を楽にしてくれるかどうかはわかりませんが、私のアプローチになると思います。

+0

私はその考えが好きです。唯一の問題は、元の質問に追加したばかりの挿入メソッドと更新メソッドです。彼らは一種の奇妙なものですが、彼らはquiresをもっと楽にします。自分の挿入や更新の方法で変数を保存する方法を結びつける方法はありますか?私は、各変数を含むために膨大な長いクエリを作成することができましたが、この$ data変数を持つ限り、すべてのクラスに対して、挿入と更新の方法が全面的に機能します。どう思いますか? – MackDaddy

1

あなたは詳細が必要な場合は、私がずっとあなたを助けることはできませんが、ロジックの面で:ビューの純粋なオブジェクト指向設計の観点から

、私はこれが最善のカートクラスを作成することによって解決されると思いますアイテムを追跡する。これは、基本的に、適切なソートのリストのラッパークラス(言語固有であり、私はPHP = Pをあまり知らない)である可能性があります。

私は、アイテムがカートの状態を把握する特別な理由は見当たりません。ほとんどの状況で、カートの追跡が理にかなっています。 (現実世界のモデリングの点では、アイテムはカートのカートを追跡しますか?Nahですが、カートは基本的にアイテムのコンテナです)

私はあなたが何をしているのかよく分かりませんあなたの2番目の質問で尋ねる - あなたは精巧にできますか? 申し訳ありません、私はより多くの助けができません。

デビッド

+0

ダビデのアドバイスをありがとう。ここには基本的な前提があります。私はアイテムの配列を持つカートクラスを持っています。しかし、これらのアイテムでは、数量も保存する必要があります。そのカートをデータベースに保存するには、アイテムとその数量をすべて保存する必要があります。 これは、このクラス拡張がどこに来るのかです。カートにリンクするアイテムは、リレーショナルデータベースのためのものであり、クエリを簡単にします。たぶん私はカートアイテムのクラスをスキップし、ちょうどこれをすべてカートクラスで管理しています...助けをありがとう! – MackDaddy