Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Userklasse: Statische oder dynamische set/get-Methoden?

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Userklasse: Statische oder dynamische set/get-Methoden?

    Hallo Leute.

    Meine Frage ist im Grunde genommen weniger technisch, sondern eher konzeptionell gesehen. Ich habe eine eigene Userklasse �* la:

    PHP-Code:
    class UserHandler {
        private 
    $data = array();
        private 
    $userid;
        
        
    /**
         * Loads the data of the assigned user into the data array.
         * @param integer $id Id of the user to be loaded (if it is empty or equals zero, the function will use the value of $_SESSION['userid'] instead)
         */
        
    public function __construct($id 0) {
    // usw. :) 
    Ganz normal eben. Ich benutze zum Abfragen von Userdaten bzw. Variablen übliche set und get-Funktionen, die z.B. so aussehen:

    PHP-Code:
    public function getEmail() {
            return 
    $this->data['email'];    
        }
        
        public function 
    setEmail($email) {
            
    updateDabase('email'$email);
        } 
    Nun existieren jedoch mittlerweile schon rund 20 dieser set und get Funktionen, was die Datei relativ unübersichtlich macht. Ich bin noch in der relativ frühen Programmierphase, d.h. ein umändern des restlichen Codes wäre noch nicht so problematisch.

    Ist es eventuell sinnvoller, anstatt so viele, statisch geschrieben Funktionen nicht einfach nur eine get und eine set-Funktion zu benutzen? �* la:

    PHP-Code:
        public function getVar($var)
        {
            switch (
    $var) {
                case 
    'email':
                    return 
    data['email'];
                    break;

                case 
    'name':
                    return 
    data['name'];
                    break;
                
                default:
                    return 
    false;
                break;
            }
        }

        public function 
    setVar($var$value)
        {
            
    updateDatabase($var$value);
        } 
    Der Gedanke kam mir, als ich mal wieder meinen Sourcecode aufgeräumt habe, und ich mich an das DRY (don't repeat yourself) erinnern musste.

    Wäre das zweite nicht sinnvoller?

  • #2
    updateDatabase
    Ich hoffe nicht jeder call erzeugt wirklich eine DB-Abfrage?!

    Zur Frage:

    Also ich mache das teilweise, wobei das bei mir auf den Zweck der Klasse ankommt. Handelt es sich um einen schnöden Datencontainer, dann reicht eine get/set-Methode voookommen aus. Die kann man dann gut gestalten, mit Existenzabfrage und Defaultwertverhalten. Auch kannst Du dann gleich überlegen, alle Daten in einer Property als Array zu speichern, ach ich sehe, das planst Du bereits. Es muss natürlich $this->data heißen und von private rate ich Dir gleich mal ab.

    Anders sieht es bei Businessobjekten aus. Alle Properties, die keinen reinen Massendaten sind, alos z.B. die Datenbankverbindung, komponierte Objekte usw. lege ich schön in gesonderten Properties und auch mit eigenen Zugriffsmethoden an (falls benötigt). Die kann man dann auch mit Type-Hints oder Prüflogik ausstatten.

    Kommentar


    • #3
      Ich schreib für jede Eigenschaft eigenen Getter und Setter. Hat in meinen Augen folgende Vorteil:

      -individuelle Prüfung
      -kommentiert sich quasi von selbst
      -Tippfehler fallen schneller auf (unkown method)
      -Autocomplete der IDE

      Kommentar


      • #4
        Zitat von MrR Beitrag anzeigen
        Hallo Leute.
        PHP-Code:
            public function getVar($var)
            {
                switch (
        $var) {
                    case 
        'email':
                        return 
        data['email'];
                        break;

                    case 
        'name':
                        return 
        data['name'];
                        break;
                    
                    default:
                        return 
        false;
                    break;
                }
            } 
        So ähnlich nutze ich es auch bei bestimmten Klassen, (Definition hat ja nikosch bereits gegeben). Die Getter-Methode würde ich jedoch nicht mit einem Switch machen, sondern eher so:

        PHP-Code:
        class UserHandler {
            private 
        $aData = array();
            private 
        $iUserid;
             
            public function 
        __construct($iId 0) {
                
        $this->iUserid $iId;
            }
            
            public function 
        getValue($sParam) {
                
        // Prüfen ob der Parameter gesetzt ist
                
        if (!isset($this->aData[$sParam])) {
                    
        // Parameter ist nicht gesetzt, false wird zurück gegeben
                    
        return false;
                }
                
        // Parameter ist gesetzt, Value wird zurück gegeben
                
        return $this->aData[$sParam];
            }

        Kommentar


        • #5
          Anstelle switch-Verhaue oder Parameter: __get und __set scheint mir hier die beste Lösung.
          tr0y hat dafür hier im Forum ein wunderschönes Beispiel geliefert:
          class HTMLTag


          LG jspit

          Kommentar


          • #6
            Anstelle switch-Verhaue oder Parameter: __get und __set scheint mir hier die beste Lösung.
            Ist letztlich die Entscheidung, ob man mit direktem Propertyzugriff arbeiten möchte. Meine Getter sehen bspw. so aus:
            PHP-Code:
              public function getData ($mKey null $mDefault null)
                {
                if (
            null === $mKey)
                  {
                  return (
            $this->_aRenderSettings);
                  }

                if (
            is_array ($mKey))
                  {
                  
            $aReturn = array ();
                  foreach (
            $mKey as $sKey => $mDefault)
                    {
                    
            $aReturn[] = $this->getData ($sKey $mDefault);
                    }

                  return (
            $aReturn);
                  }

                return (
            array_key_exists ($mKey $this->_aRenderSettings)
                          ? 
            $this->_aRenderSettings[$mKey]
                          : 
            $mDefault
                       
            );
                } 
            Da kann man dann schon etwas mehr mit anstellen.

            Kommentar


            • #7
              Auch nicht von schlechten Eltern, mit rekursiven Aufruf, muß ich mir mal in Ruhe reinziehen..

              Kommentar


              • #8
                PHP-Code:
                <?php

                class Model {
                    protected 
                $property;
                        
                    public function 
                __construct(array $loadProperties = array())
                    {
                        
                $this->property = array();
                        
                $this->setProperties();
                        
                $this->load($loadProperties);
                    }
                    
                    public function 
                __get($key)
                    {
                        return 
                $this->get($key);
                    }
                    
                    public function 
                get($key)
                    {
                        if (
                is_array($key))
                        {
                            
                $array &= $key;
                            
                $arrayReturn = array();
                            
                            foreach (
                $array as $key => $value)
                            {
                                
                $arrayReturn[$key] = $this->get($key);
                            }
                            
                            return 
                $arrayReturn;
                        }
                        else if (isset(
                $this->property[$key]))
                        {
                            return 
                $this->property[$key];
                        }
                        
                        return 
                null;
                    }
                    
                    public function 
                __set($key$value)
                    {
                        
                $this->set($key$value);
                    }
                    
                    public function 
                set($key$value)
                    {
                        if (
                is_array($key))
                        {
                            
                $array &= $key;
                            foreach (
                $array as $key => $value)
                            {
                                
                $this->set($key$value);
                            }
                        }
                        else if (isset(
                $this->property[$key]))
                        {
                            
                $this->property[$key] = is_null($value) ? '' $value;
                            return 
                true;
                        }
                        
                        return 
                false;
                    }
                    
                    public function 
                load(array $property)
                    {
                        
                $count 0;
                        foreach (
                $property as $key => $value)
                        {
                            if (
                $this->set($key$value))
                                
                $count++;
                        }
                        
                        return 
                $count;
                    }
                    
                    public function 
                save()
                    {
                        
                // Speichern
                    
                }
                    
                    protected function 
                setProperty($key$default '')
                    {
                        
                $this->property[$key] = $default;
                    }
                    
                    public function 
                setProperties() {}
                }

                class 
                User extends Model {

                    public function 
                setProperties()
                    {
                        
                $this->setProperty('username''defaultUsername');
                        
                $this->setProperty('email''defaultEmail');
                    }
                }

                $user = new User(array('username' => 'lol'));
                var_dump($user->username);
                var_dump($user->email);
                $user->username 'Administrator';
                var_dump($user->username);

                Kommentar


                • #9
                  Warum nicht eines der zahlreichen Frameworks verwenden, in denen diese Frage schon gefragt und geloest wurde?

                  Kommentar


                  • #10
                    Nicht jeder Trivialcode braucht ein Framework.

                    Kommentar


                    • #11
                      Klar, aber das ist ja kein Trivialcode. So wie ich das verstehe versucht der OP das Model-Pattern nachzubauen. Inklusive DB-Anbindung und Streuseln.

                      Kommentar


                      • #12
                        Keine Ahnung, wo Du das herausgelesen haben willst. Und selbst wenn: Auch MVC muss nicht irre kompliziert sein. Das Pattern an sich ist eigentlich recht einfach.

                        Kommentar


                        • #13
                          Wer den direktem Propertyzugriff nicht so mag, dem bieten die Magic Methods noch weitere Möglichkeiten.
                          Wie weit man dies treiben kann, soll folgender Ansatz als Alternative zu den von MrR #1 eingangs gezeigten Code verdeutlichen:

                          PHP-Code:
                          class basis{
                              protected 
                          $property = array();
                             
                              public function 
                          __call($name,$arguments)
                              {
                                  
                          $key substr($name,3);
                                  if(empty(
                          $key)) return NULL;
                                  switch (
                          substr($name,0,3)) {
                                      case 
                          'set':
                                      
                          $this->property[$key] = isset($arguments[0]) ?  $arguments[0] : NULL;
                                      break;

                                  case 
                          'get':
                                      return isset(
                          $this->property[$key]) ?  $this->property[$key] : NULL
                                
                                  default:
                                      return 
                          NULL;
                              }
                            }
                          }

                          //test
                          $m = new basis();
                          $m->setName("Meier");
                          $m->setCity("Hamburg");
                          echo 
                          "Name: ".$m -> getName()." City: ".$m -> getCity();
                          //Name: Meier City: Hamburg 
                          LG jspit

                          Kommentar


                          • #14
                            Ich habe das mal mit magischen Methoden und Zuweisungen umgesetzt. Da kann man ggf. auch generische Validierungen durchführen

                            PHP-Code:
                            class User {
                                
                                private 
                            $name '';
                                
                                private 
                            $email '';
                                
                                public function 
                            __get($k) {
                                    if (
                            property_exists($this$k)) {
                                        return 
                            $this->$k;
                                    } else {
                                        throw new 
                            Exception('Member ' $k ' does not exist');
                                    }
                                }
                                
                                public function 
                            __set($k$v) {
                                    if (
                            property_exists($this$k)) {
                                        
                            // Evtl.. irgendein Validierungsmechanismus
                                        
                            $this->$k $v;
                                    } else {
                                        throw new 
                            Exception('Member ' $k ' does not exist');
                                    }
                                }

                            Dann kann man per Zuweisung damit arbeiten und kann trotzdem Validierungen implementieren.

                            Kommentar


                            • #15
                              Zitat von nikosch Beitrag anzeigen
                              Ich hoffe nicht jeder call erzeugt wirklich eine DB-Abfrage?!
                              Derzeit löse ich es so, dass jede Änderung erstmal nur in das Datenarray der Klasse geschrieben werden, & am Ende des Skripts mit Hilfe einer Kopie des originalen Arrays die veränderten Daten zusammen an die Datenbank geschickt werden, um die Datenbankanfragen gering zu halten. Ich sollte die Funktion eventuell besser bennen.

                              Zitat von nikosch Beitrag anzeigen
                              Es muss natürlich $this->data heißen und von private rate ich Dir gleich mal ab.
                              Ich bin mir nicht ganz sicher warum, könntest du mir erklären, wieso du mir hier von private abrätst? Meinst du protectet hier als Alternative?

                              Zitat von Joachim Beitrag anzeigen
                              PHP-Code:
                                  public function __get($key)
                                  {
                                      return 
                              $this->get($key);
                                  }
                                  
                                  public function 
                              get($key)
                                  {
                                      if (
                              is_array($key))
                                      {
                              //usw.. 
                              Darf ich mal fragen, wieso du hier eine magische Funktion benutzt, die bei dir ur dazu dient, auf eine normaler "weiterzuleiten"?

                              Überhaupt, was ist der Vorteil darin, die magische Funktionen zu nutzen, und den Zugriff nicht wie nikosch vorgeschlagen hat zu regeln.

                              Vielen Dank für all die Hilfe! Ihr seid großartig.

                              Kommentar

                              Lädt...
                              X