Frage zu Klassenstruktur

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Frage zu Klassenstruktur

    Hallo erstmal

    Also ich bin gerade dabei eine Klasse zu schreiben, deren Methoden Zugriff auf eine MySQL-Db benötigen. Und wenn schon objekt-orientiert, dann soll für den DB-Zugriff Das Modul mysqli zum Einsatz kommen.
    Meine Idee zur Vorgehensweise ist folgende: da eh jede Methode meiner Klasse DB-Zugriff benötigt, wollte ich im Konstruktor ein neues mysqli-Objekt erzeugen und dann im Destruktor mysqli->Close() aufrufen. Die Methoden müssen sich dann weder um die Herstellung noch das Trennen der Verbindung bemühen, sondern sollen direkt mit dem im Konstruktor erzeugten mysqli-Objekt Arbeiten können.
    Ist diese Vorgehensweise sinnvoll, oder sollte sich jede einzelne Methode selbst um die Verbindung kümmern?

    Dann habe ich noch eine Frage zur Sichtbarkeit des im Konstruktor erzeugten mysqli-Objekts. Bisher ist dieses ja nur innerhalb des Konstruktors sichtbar, die anderen Methoden sollen ja allerdings auch Zugriff darauf haben. Muss ich also außerhalb des Konstruktors schon so etwas wie "$db = new Object()" deklarieren, welches ich dann innerhalb des Konstruktors mit mysqli initialisiere, oder was ist da die beste Lösung?


    Danke schonmal
    Zuletzt geändert von INC.; 03.08.2008, 15:50.

  • #2
    Das muß man nicht mehr selber bauen...
    Es gibt ja schon "doctrine" usw.

    Dir reicht doch bestimmt 1 Verbindung zur DB.
    Also ist es Unsinn, wenn jedes Object seine eigene Aufbaut.
    Wir werden alle sterben

    Kommentar


    • #3
      Ist diese Vorgehensweise sinnvoll, oder sollte sich jede einzelne Methode selbst um die Verbindung kümmern?
      wieso. da hast du schon so schöne dinge wie den konstruktor und destruktor, also nutze sie auch.
      Bisher ist dieses ja nur innerhalb des Konstruktors sichtbar
      wenn du sie als private deklariert hast.
      die anderen Methoden sollen ja allerdings auch Zugriff darauf haben
      die verbindung kann ruhig private sein. siehe beispiel-/pseudo-code
      PHP-Code:
      class MySQL
      {
        private 
      $con;
        private 
      $result;

        public function 
      __construct ($host$user$password$database)
        {
          
      $this -> con mysql_connect ($host$user$password);
          if (
      is_resource ($this -> con))
          {
            
      mysql_select_db ($database);
          }
        }

        public function 
      __destruct ()
        {
          if (
      is_resource ($this -> con))
          {
            
      mysql_close ($this -> con);
          }
        }

        public function 
      doQuery ($query)
        {
          if (
      $this -> result mysql_query ($query))
          {
            while (
      $row mysql_fetch_assoc ($this -> result))
            {
              ...                    
            } 
          }
        }
      }

      peter 
      Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
      Meine Seite

      Kommentar


      • #4
        Danke euch beiden. Jetzt bleibt noch ein Problem, welches ich gerade nicht durchschauen kann, und zwar das Schlüsselwort "this".

        In richtigen Programmiersprachen (C# etc..) verwendet man "this", um Namenskonflikte mit lokalen Variablen zu vermeiden.
        Gibt es eine Eigenschaft UND eine lokale Variable innerhalb eines Objekts/Klasse, welche exakt den selben Namen haben, so kann man die Eigenschaft über "this.Namen" und die lokale Variable nur über "Namen" ansprechen.
        Gibt es jedoch keine lokale Variable mit dem selben Namen, so braucht man kein "this", um die Eigenschaft anzusprechen, sondern kann einfach nur "Namen" schreiben (so wie man es zuvor mit der lokalen Variablen gemacht hat, als diese noch existierte).
        Kurz gesagt: gibt es keine lokale Variable, die so heißt wie eine Eigenschaft, braucht man "this" auch niemals benutzen.


        In PHP scheint dies aber irgendwie anders zu sein. Mein Destruktor sieht so aus:

        PHP-Code:
        public function __destruct()
              {
                  if (
        $mysql instanceof mysqli) {
                      
        $mysql->close();
              }
              } 

        $mysql habe ich übrigens zur Eigenschaft gemacht wie von Kropff vorgeschlagen, sie ist im Desktruktor also eigentlich bekannt. Das ganze geht nur nicht! Ändere ich den Code aber so ab:

        PHP-Code:
        public function __destruct()
              {
                  if (
        $this->mysql instanceof mysqli) {
                      
        $this->mysql->close();
              }
              } 
        Dann funktioniert es. Warum brauche ich aber "this"? es gibt in der Klasse weit und breit keine lokale Variable, die mysql heißt. normalerweise müsste ich doch auch nur "mysql" schreiben dürfen.
        Muss ich in PHP etwa Eigenschaften immer mit "this" ansprechen?

        Kommentar


        • #5
          Muss ich in PHP etwa Eigenschaften immer mit "this" ansprechen?
          Jep, so ist es!

          Kommentar


          • #6
            Okay, danke

            Bleibt noch eine letzte Frage: ich habe eine private "validate_input" Methode, die die übergebenen Parameter mittels Regex auf Richtigkeit prüft. Sind die Parameter falsch, so soll abgebrochen werden.
            Normalerweise fällt einem als erstes sowas ein (Pesudocode):

            if(param == falsch) die("fehlermeldung");

            Allerdings: Wird bei die() der Destructor überhaupt noch ausgeführt? Denn die Datenbank, von der wir es oben hatten, soll ja noch geschlossen werden. Abgesehen davon ist mir die() eh zu hart, denn es wird ja dann auch alles außerhalb des Objekts beendet.

            Ich dachte anschliessend, folgendes wäre eine gute Lösung:

            if(param==falsch) echo "Fehlermeldung";
            unset($this);

            Jedoch lese ich gerade auf php.net:

            Hinweis: Es ist ab PHP 5 nicht mehr möglich, $this innerhalb einer Objektmethode zu löschen.
            Wie würdet ihr das ganze lösen?


            @Kropff: aka Peter Kropff? Ist ja lustig, ich lese unabhängig von dem Forum hier schon seit ein paar Tagen auf peterkropff.de, bin mit Google draufgestoßen. Schönes Ding!
            Falls du es auch als sinnvoll erachtest, könntest du ja bei der kurzen Erklärung von "this" auf deiner Seite ja noch erwähnen, dass man das Schlüsselwort bei PHP immer braucht (siehe Problematik oben). Imho ist das für Umsteiger von anderen Sprachen sonst erstmal verwirrend.


            edit: wäre das eine gute Lösung? validate_input gibt einfach true oder false zurück. Die aufrufende Stelle macht bei false einfach garnix, das Objekt "läuft aus". kommt ja einem Abbruch ziemlic nahe.
            Zuletzt geändert von INC.; 04.08.2008, 14:40.

            Kommentar


            • #7
              Wenn innerhalb einer Methode abgebrochen werden MUSS, wirft man eine Exception.
              http://www.php.net/manual/de/language.exceptions.php
              Wir werden alle sterben

              Kommentar


              • #8
                Wie würdet ihr das ganze lösen?
                Exception mit der Meldung rauswerfen. Und in der aufrufenden Datei mittels try...catch-Block abfangen und entsprechend reagieren. imho wird der Destruktor nach die() nicht mehr ausgeführt. Wenn es aber nur um das Schliessen der Verbindung geht, dann wird das am Ende des Scripts so oder so von selber erledigt.
                Gutes Tutorial | PHP Manual | MySql Manual | PHP FAQ | Apache | Suchfunktion für eigene Seiten

                [color=red]"An error does not become truth by reason of multiplied propagation, nor does truth become error because nobody sees it."[/color]
                Mohandas Karamchand Gandhi (Mahatma Gandhi) (Source)

                Kommentar


                • #9
                  Jop, daran hab ich auch gedacht, aber ich hätte gleich das ganze Beispiel zeigen sollen.. wie ihr sagt, wird ja nur innerhalb der Methode abgebrochen, nicht das ganze Objekt beendet.

                  PHP-Code:

                  public function __construct($host$user$pass$database)
                        {
                            try {
                                @
                  $this->mysql = new mysqli($host$user$pass$database);
                                if (
                  mysqli_connect_errno()) {
                                    throw new 
                  Exception("Error "mysqli_connect_errno(). ": ".mysqli_connect_error());
                                }
                            }
                            catch (
                  Exception $e) {
                                echo 
                  $e->getMessage();
                            }
                        } 
                  Das ist also der Konstruktor. Funktioniert soweit gut, NUR: die mysql-Eigenschaft wird immer vom Typ mysqli sein, auch wenn die 4 Zugangsparameter falsch sind und keine Verbindung hergestellt werden konnte. Dann erhält man ein defektes mysqli-Objekt.

                  Die anderen Methoden der Klasse werden evt. trotzdem ausgeführt und wollen mysql benutzen, auch wenn es defekt ist -> crash. Deshalb hab ich nach einer die() Alternative vesucht.. wenn mysql defekt ist, bringt die ganze Klasse nichts.

                  Bevor die Exception geworfen wird, könnte ich noch ein unset(this->mysql) einfügen und dann in allen Methoden erst prüfen, ob mysql noch existiert. Allerdings wirft PHP dann eine Notice, dass die Eigenschaft hopps gegangen ist.

                  Oder habt ihr das mit den Exceptions anders gemeint?


                  //edit: oje...ich könnte ja auch einfach nur statt unset($this->mysql) zu schreiben $this->mysql = "" setzen. Wäre es dann "resettet" und vom mysqli-Objekt befreit? Oder gibts fürs Zurücksetzen gar eigene Funktionen?
                  Zuletzt geändert von INC.; 04.08.2008, 17:25.

                  Kommentar


                  • #10
                    macht irgendwie wenig sinn:
                    exception werfen, fangen und ausgeben alles innerhalb einer methode.
                    dann kannst du es auch gleich so schreiben:
                    PHP-Code:
                    if(!bedingung)
                    {
                     echo 
                    'fehler';

                    also throw new Exception ... ist ok

                    der try-catch-block gehört irgendwo außerhalb hin.

                    Kommentar


                    • #11
                      Ja da hast du recht, habs geändert. Die Probleme haben sich übrigens in Luft aufgelöst, und ja, $var = "" scheint die Vairable wirklich zu resetten bzw. das Objekt von ihr zu entfernen.

                      Das einzige was mich noch plagt, ist aus einem mysqli-Objekt herauszuquetschen, mit welcher Datenbank es verbunden ist... scheint aber keine nützliche Eigenschaft zu haben, die einem das sagt.


                      Danke nochmal
                      Zuletzt geändert von INC.; 04.08.2008, 22:50.

                      Kommentar


                      • #12
                        Das einzige was mich noch plagt, ist aus einem mysqli-Objekt herauszuquetschen, mit welcher Datenbank es verbunden ist... scheint aber keine nützliche Eigenschaft zu haben, die einem das sagt.
                        Da scheint es keine direkte Methode für zu geben, ist aber auch i.d.R. nicht notwendig. Aber du kannst ja beim Erstellen des Objektes den entsprechenden Wert als Klassenmember mitspeichern.

                        Kommentar

                        Lädt...
                        X