2009-06-28 10 views
0

So habe ich einen Artikel Klasse wie folgt:PHP Objekterweiterung Frage

 

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

    } 

Meine Frage ist, was der beste Weg wäre, diese Klasse mit der Datenstruktur zu erweitern, wie ich es haben? Ich möchte grundsätzlich eine andere Klasse für einen Gegenstand in einem Einkaufswagen haben. Einige zusätzliche Felder wären also Quantität, Wagen-ID usw. Oder gibt es einen besseren Weg, dies zu tun, ohne die Klasse zu erweitern?

Bei einer anderen Anmerkung, sagen wir, ich habe eine andere Variable $ price, die nicht direkt in der Datenbank gespeichert wird. Also mache ich es zu einer öffentlichen Variable, aber ich müsste Hilfsmethoden machen, um darauf zuzugreifen, oder? Wenn das der Fall ist, ist mein $ data array die beste Lösung für diesen Item?

Vielen Dank im Voraus.

Antwort

1

Ich bin nicht 100% sicher, welche Art der Nutzung der privaten $data Variable, die Sie tun könnten, so ist hier meine Tendenz einen etwas anderen Ansatz zu nehmen wäre.

Statt alle Ihre Daten von Gruppierungsfeldern in einem einzigen privaten Variablen des Objekts, würde ich jedes Feld eine private Variable macht selbst, das heißt:

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

Dies würde Ihr Problem sofort löst mit öffentlich verfügbaren Daten mit Felder, da Sie solche Felder einfach als öffentliches Mitglied deklarieren können. Öffentliche Mitglieder benötigen keinen Getter und Setter, also müssen Sie sich keine Sorgen machen ... Sie könnten einfach über $this->price (intern) oder $item->price (extern) auf sie zugreifen. Speichert Ihnen etwas Code. Und es wäre eine schnelle Änderung Ihrer populate() Funktion, um alle Ihre neuen Eigenschaften zu setzen, als alles, was Sie tun müssten, würde $this->$$key statt $this->data[$key] setzen.

nun mit der Nutzung von __set() und __get(), sieht es aus wie Sie den privaten $data Mitglied auch von außerhalb des Objekts in der Lage sein zugreifen möchten. Es gibt keinen Grund, warum Sie das nicht fortsetzen können, indem Sie jedes Feld separat als privat deklarieren lassen. __set() und __get() wird genau die gleiche Art und Weise arbeiten, dann würden Sie nur eine geringfügige Anpassung benötigen, das heißt:

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

Als letzten Bonus, die Klasse erweitert wird einfacher, weil Sie müssen alle Felder nicht neu deklarieren in ihrer Gesamtheit, wenn Sie die Eigenschaft $data überschreiben möchten.Sie fügen einfach die neuen Felder Ihrer Kinder als neue private Mitglieder hinzu.

Also ich bin nicht sicher, ob das Ihr Leben einfacher macht, aber ich denke, dass mein Ansatz wäre.

+0

Ich mag diese Idee, das einzige Problem sind die Einfüge- und Update-Methoden, die ich gerade zur ursprünglichen Frage hinzugefügt habe. Sie sind irgendwie komisch, aber sie machen die Quests viel einfacher. Gibt es eine Möglichkeit, wie ich Ihre Methode zum Speichern von Variablen mit meinen Methoden zum Einfügen und Aktualisieren binden könnte? Zugegeben, ich könnte eine riesige Abfrage für die Einbeziehung jeder Variablen machen, aber so funktionieren meine Einfüge- und Aktualisierungsmethoden für alle meine Klassen auf der ganzen Linie, solange sie diese Variable $ data haben. Was denken Sie? – MackDaddy

1

Wenn Sie Besonderheiten brauchen, kann ich Ihnen nicht viel helfen, aber in Bezug auf die Logik:

Von einem rein objektorientierte Sicht des Design, ich glaube, dies am besten durch die Schaffung einer Cart-Klasse gelöst Gegenstände im Auge behalten. Es könnte im Grunde eine Wrapper-Klasse für eine Liste einer geeigneten Sorte sein (sprachspezifisch, und ich weiß nicht viel PHP = P).

Ich sehe keinen besonderen Grund dafür, dass ein Gegenstand den Überblick über den Wagen behält, in dem er sich befindet - in den meisten Situationen ist es sinnvoller, den Wagen im Auge zu behalten. (In Sachen real-world Modelling: verfolgen Artikel den Warenkorb, in dem sie sich befinden können oder nicht? Nein. Aber Einkaufswagen sind im Grunde nur Container für Artikel.)

Ich bin mir nicht ganz sicher, was Sie sind Frage in Ihrer zweiten Frage - Könnten Sie bitte erläutern? Sorry, ich kann nicht mehr helfen.

David

+0

Danke für den Rat David. Hier ist die Grundvoraussetzung. Ich habe eine Wagenklasse mit einer Reihe von Gegenständen. Aber mit diesen Dingen muss ich auch die Menge speichern. Jetzt, um diesen Warenkorb in einer Datenbank zu speichern, muss ich auch alle Artikel und ihre Mengen speichern. Das ist, wo diese Klassenerweiterung kommt. Das Element, das mit dem Warenkorb verknüpft ist, ist nur für die relationale Datenbank, erleichtert meine Abfragen. Vielleicht überspringe ich die Cart-Item-Klasse und lasse das alles von der Cart-Klasse verwalten ... Danke für die Hilfe! – MackDaddy