Rollo: Objektorientierung - Frage

Hallo,
ich habe eine Frage zur objektorientierten Programmierung in PHP.

Nehmen wir folgenden Test-Fall:

ein HTML-Formular besitzt drei Checkboxen. Dieses Formular schicke ich per submit ab, übergebe einem PHP-Objekt diese Daten

  
$myObject = new object();  
$myObject->setBox1($_POST["box_1"]);  
$myObject->setBox2($_POST["box_2"]);  
$myObject->setBox3($_POST["box_3"]);  

und lese die Daten wieder aus, um die Status in den Checkboxen entsprechend anzuzeigen

  
$myObject->getBox1();  
$myObject->getBox2();  
$myObject->getBox3();  

Die Daten wurden bisher nicht in einer Datenbank gespeichert. Erst wenn ich noch ein Häkchen (Daten speichern) aktiviere, und dann den submit-button drücke, werden die Werte wieder gesetzt und dann in der Datenbank gespeichert.

  
$myObject = new object();  
$myObject->setBox1($_POST["box_1"]);  
[..]  
$myObject->save();  

Also das gleiche wie vorher

Nun möchte ich nach dem Speichern der Daten wieder meine Checkboxen mit den Werten füllen. Dazu würde ich wieder die getter aufrufen, wie gehabt. Aber ich möchte nun rein testweise dazu die Daten aus der Datenbank verwenden (ich weiß, es sind die gleichen Werte wie die aus P_POST).

  
$myObject->getBox1();  

getBox1() soll also die Daten aus der Datenbank holen, und nicht den Wert, der von $_POST übergeben wurde. Wie macht man das?

a) man hat in der Methode getBox1() einen Schalter, der der Methode mitteilt, ob sie die Daten aus der DB nehmen soll, oder den aktuellen Zustand des Objektes

b) man initialisiert das Objekt mit den Daten aus der DB nochmal neu

c) man hat eine eigene Methode getBox1DB(), die die Daten immer nur aus der Datenbank holt

d) denke ich komplett falsch?

das ist nur ein Testcase, wie gesagt.

vielen Dank

  1. Hallo,

    persönlich löse ich das immer so:

      
    function get_var($force_reload = FALSE) {  
      $this->var = $_POST['var'];  
      
      if((empty($this->var) && !$this->var_cached) || $force_reload) {  
        $this->load_db_var();  
      }  
      return($this->var);  
    }  
      
    function load_db_var () {  
      //deine DB abfrage hier  
      $this->var = result;  
    }  
      
    
    

    So kann man sich sicher sein, dass immer wenn der getter aufgerufen wird ein entsprechender Wert zurückkommt. Wenn halt nicht aus dem POST, dann aus der DB.

    (Wobei ich immer die DB vorziehen würde, die ist schneller und ich muss mir nicht ganz so viele Gedanken über möglich Fehler / Angriffe machen.)

    1. $this->var = $_POST['var'];

        
      Und wofür ist das nötig?  
      In deinem Code kannst du doch direkt auf $\_POST zugreifen, das Sichtbarmachen im gesamten Objekt mit einer Variablen ist dabei völlig überflüssig,ja erhöht sogar die Gefahr von Programmierfehlern. 
      
  2. Tach!

    ein HTML-Formular besitzt drei Checkboxen. Dieses Formular schicke ich per submit ab, übergebe einem PHP-Objekt diese Daten

    $myObject = new object();

    $myObject->setBox1($_POST["box_1"]);
    $myObject->setBox2($_POST["box_2"]);
    $myObject->setBox3($_POST["box_3"]);

    
    >   
    > und lese die Daten wieder aus, um die Status in den Checkboxen entsprechend anzuzeigen  
    > ~~~php
    
    $myObject->getBox1();  
    
    > $myObject->getBox2();  
    > $myObject->getBox3();
    
    

    Warum Getter und Setter? Bringen die dir einen konkreten Vorteil oder verbrauchen die nur einen Methodenaufruf, nur weil andere Systeme das auch so machen?

    Nun möchte ich nach dem Speichern der Daten wieder meine Checkboxen mit den Werten füllen. Dazu würde ich wieder die getter aufrufen, wie gehabt. Aber ich möchte nun rein testweise dazu die Daten aus der Datenbank verwenden (ich weiß, es sind die gleichen Werte wie die aus $_POST).

    Sollte man annehmen, solange du dich nicht in einem System mit nebenläufigen Prozessen befindest. Solche gibts aber kaum im Web-Umfeld. So zumindest die theoretische Betrachtung. Rein praktisch wird vielleicht die Wahrscheinlichkeit eher gering sein, dass dir ein anderer Prozess die Daten unterm Arsch weg ändert.

    getBox1() soll also die Daten aus der Datenbank holen, und nicht den Wert, der von $_POST übergeben wurde. Wie macht man das?
    a) man hat in der Methode getBox1() einen Schalter, der der Methode mitteilt, ob sie die Daten aus der DB nehmen soll, oder den aktuellen Zustand des Objektes

    Dann macht die Methode eine Datenbankanfrage für den einen Wert und eine weitere für den nächsten und so weiter? Oder willst du dir hier Nebenwirkungen reinbringen und bei einer Abfrage gleich alle anderen Werte mit ändern?

    b) man initialisiert das Objekt mit den Daten aus der DB nochmal neu

    Besser ist das.

    dedlfix.

  3. Hallo,

    getBox1() soll also die Daten aus der Datenbank holen, und nicht den Wert, der von $_POST übergeben wurde. Wie macht man das?

    Deine Anwendung geht mit dem HTTProtokoll: Wenn das Form aufgerufen wird, hast Du ein GET, in dem Fall holst Du die Daten aus der DB zur Darstellung des Forms mit den Checkboxen. Wenn ein Submit gemacht wird, hast Du einen POST, dann gehen die Daten genau andersherum.

    d) denke ich komplett falsch?

    Nein, Du bist auf dem richtigen Weg ;)
    Idee: Die Checkboxen bekommen alle den gleichen Namen, dann hast Du ein Array oder abstrakt gesagt: Eine Datenstruktur und die sieht für den Hin- wie für den Rückweg immer gleich aus. Es wäre zu überlegen, wie diese Datenstruktur aussehen könnte (Stift, Zettel...).

    Die Datenstruktur (ein schönes Array oder ein Objekt) ist nur der Datenträger. zur Darstellung hast Du in Deiner Reponseklasse eine Methode, welche dieses Objekt vom DB-Interface bekommt und in das HTML-Template schreibt. Für den Submit-Fall hast Du eine Methode, welche dieselbe Datenstruktur (Objekt) aus dem POST liest und an die DB übergibt: getter() und setter().

    Hotti

  4. Moin!

    Ich sammle mal:

    $myObject = new object();
    $myObject->setBox1($_POST["box_1"]);
    $myObject->setBox2($_POST["box_2"]);
    $myObject->setBox3($_POST["box_3"]);
    $myObject->getBox1();
    $myObject->getBox2();
    $myObject->getBox3();
    $myObject->save(); // In DB speichern

    
    >   
    > d) denke ich komplett falsch?  
      
    Was auch immer dein Objekt jetzt genau tun soll, es tut zuviel. Aus der Beschreibung entnehme ich mindestens folgende Features:  
      
     - Formulardaten entgegennehmen  
     - Daten oder wohlmöglich ganzes HTML mit Formulardaten wieder ausspucken  
     - Speichern der Daten in einer Datenbank  
     - Lesen der Daten aus der Datenbank  
     - Pro Datenfeld eine eigenständige Methode zum Schreiben und Lesen  
      
    Jeder der Teilaspekte ist für sich genommen schon so komplex, dass man ihn in der Regel nicht mit einer einzigen Klasse lösen wird. Wenn ich mal auf größere Frameworks schaue, dann findet man dort meist:  
      
    Eine Klasse, die ein Formular repräsentiert. Pro Formularelement weitere Klassen. Validierung von Formulardaten in eigenen Validatorklassen. Damit hat man dann den Formularteil abgedeckt.  
      
    Datenspeicherung in der Datenbank hat auch mindestens drei Klassen: Die DB-Verbindung, ein Ergebnisobjekt der Abfrage und dann Einzelobjekte der einzelnen Datenzeilen. Tendentiell sind es mehr, wenn man noch eine Abstraktionsschicht für unterschiedliche Datenbanken mit einrechnet.  
      
    Und das ganze ist sicherlich eingebettet in irgendein Konstrukt, welches das Formular an den Browser ausgibt und das abgeschickte Formular irgendwie entgegennimmt.  
      
      
    Objektorientierung heißt auch, dass das Ganze größer sein kann als die Summe seiner Teile. Indem man pro Klasse nur eine Aufgabe erledigt, erlaubt man sich damit, diese Klasse später auch für andere Dinge wiederzuverwenden.  
      
    Ach ja: Code wiederzuverwenden ist sowieso eine gute Idee. Alle wichtigen Web-Probleme, die man üblicherweise hat, sind bereits gelöst worden. Die Aufgabe besteht darin, diese gelösten Probleme in Form von Code im Internet zu finden und zu benutzen, und sich seine Zeit nicht damit zu verschwenden, die bereits gelösten Probleme erneut zu lösen. Dann kann man sich in der Zeit nämlich mit den Problemen beschäftigen, für die es noch keine Lösung gibt.  
      
     - Sven Rautenberg