Ankündigung

Einklappen
Keine Ankündigung bisher.

Implementierung vieler Getter bzw. Setter-Methoden

Einklappen

Neue Werbung 2019

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

  • #16
    Zitat von nikosch Beitrag anzeigen
    Getter und Setter dienen zur Definition des Objektinterface.
    Wenn man unter Objektinterface das versteht, was einem das interface Schlüsselwort in PHP ermöglicht.

    Zitat von axelf Beitrag anzeigen
    PHP-Code:
    public function setBar($value){
      if (
    is_int($value)){
        
    $this->bar $value
      }else {
        throw new 
    Exception('Integer expected');
      }
    }

    public function 
    getBar(){
        return 
    $this->bar;

    Das Problem dabei ist, dass dann in der Abfolge
    1. Klasse bekommt public Eigenschaft, weil keine Prüfungen erforderlich sind,
    2. Prüfungen der Eigenschaft werden erforderlich,
    3. Klasse wird umgeschrieben.

    die Schnittstelle geändert wird (also die Art wie die Klasse benutzt wird). Dadurch muss nicht nur die Klasse geändert werden, sondern auch alle Stellen an denen die Klasse verwendet wird. Soetwas möchte man vermeiden.

    In Java wird deshalb auf public Eigenschaften verzichtet und alles über Getter und Setter abgewickelt. In PHP und C# ist das nicht nötig.
    Meinungen, die ich geäußert habe, sind nicht notwendigerweise meine eigenen. Abweichungen von der deutschen Rechtschreibung unterliegen dem Urheberrecht, dürfen aber unter den Bedingungen von verwendet werden

    Kommentar


    • #17
      # Klasse bekommt public Eigenschaft, weil keine Prüfungen erforderlich sind,
      Und warum? Außer bei ganz einfachen Containern benutze ich so gut wie nie public.
      --

      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
      Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


      --

      Kommentar


      • #18
        Ich auch nie, ist schon lecker allein fürs Debuggen: Wann wird der Wert gesetzt und von wem. Bei public hast du da ohne große Umbauarbeiten (Property weg und __set implementieren) wenig Chancen.
        "Mein Name ist Lohse, ich kaufe hier ein."

        Kommentar


        • #19
          Das Problem bei den magischen Methoden ist IMHO das man kein Type Hinting mehr machen kann und Properties auch nicht als Read-Only veröffentlichen kann. Beim Setzen auf public verstößt man gegen das Information Hiding Prinzip. Die Lösung mit dem Switch ist am aller schlimmsten: Properties als Strings abfragen?! Nicht schön.

          Aus Sicht der Programmiermethodik bleiben in PHP also nur die manuellen/generierten Getter und Setter. Wobei die Bequemlichkeit durchaus auch bei mir manchmal gegen das Prinzip siegt...

          Kommentar


          • #20
            Eigenschaften sind bei mir (fast) grundsätzlich protected/private. Zum Schreiben gibt es explizite Setter-Methoden. Zum lesen nutze ich meist __get(). Gelesen werden dürfen meistens eh alle Eigenschaften, von daher beuge ich mich da meiner Bequemlichkeit.

            Kommentar


            • #21
              Properties als Strings abfragen?! Nicht schön.
              Geht ja nun nicht anders. __call liefert den Methodennamen, __get den Propertynamen als String. Wonach sollst Du sonst handeln. Ob Du das nun im switch bedienst oder gleich als Arrayschlüssel benutzt ist doch reine Geschmackssache.
              --

              „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
              Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


              --

              Kommentar


              • #22
                Im Switch muss man es explizit nochmal tippen. Also eine Fehlerquelle mehr, bzw. etwas an das man beim Refactoren denken muss, wenn man den Namen der Property anpasst. Mein Geschmack sagt: Je weniger Fehlerquellen, desto besser

                Kommentar


                • #23
                  Wie ich gestern festgestellt habe, muss man bei Verwendung der __get-Methode vorsichtig sein. Bei Nutzung von Eigenschaften in Methoden die Referenzen erwarten werden diese Referenzen nicht auf die Objekt-Eigenschaft gelegt wenn die Eigenschaft über __get geholt wird:
                  PHP-Code:
                  <?php
                  error_reporting
                  (E_ALL E_STRICT);
                  class 
                  foo {
                      protected 
                  $bar;
                      
                      public function 
                  __construct() {
                          
                  $this->bar "Hallo Welt!";
                      }
                      public function 
                  __get($property) {
                          if(!
                  property_exists($this,$property)) {
                              throw new 
                  InvalidArgumentException("Property {$property} doesn't exist");
                          }
                          return 
                  $this->$property;
                      }
                      public function 
                  setBar($value) {
                          
                  $this->bar $value;
                      }
                  }
                      
                  $foo = new foo();
                      echo 
                  $foo->bar;    // Ausgabe: Hallo Welt!
                      
                  $db = new mysqli("localhost","root","","tests");
                      
                  $sql "INSERT INTO test SET test=?";
                      
                  $res $db->prepare($sql);
                      
                  $res->bind_param("s",$foo->bar);  // Notice: Indirect modification of overloaded property foo::$bar has no effect in /var/www/overload.php on line 24
                      
                  $res->execute();  // Eintrag: Hallo Welt!
                      
                  $foo->setBar("Und tschüß");
                      echo 
                  $foo->bar;   // Ausgabe: Und tschüß
                      
                  $res->execute();  // Eintrag: Hallo Welt!
                  ?>
                  Verwendet man die SPL_Types und hat somit auch Strings, Integers etc. als Objekte, so besteht diese Problematik nicht. Da die aber experimentell und auch nicht default-mäßig verfügbar sind ist natürlich die Frage, inwieweit man sich darauf verlassen will.

                  Kommentar


                  • #24
                    werden diese Referenzen nicht auf die Objekt-Eigenschaft gelegt wenn die Eigenschaft über __get geholt wird:
                    Wie sollten sie auch - sie existieren ja auch nicht als Eigenschaften.
                    --

                    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                    --

                    Kommentar


                    • #25
                      Zitat von nikosch Beitrag anzeigen
                      Wie sollten sie auch - sie existieren ja auch nicht als Eigenschaften.
                      Klar, das ist richtig. Wenn man es einmal realisiert hat ist das ein normales logisches Verhalten. Aber wenn man erstmal nicht groß drüber nachdenkt kann einem da schonmal leicht ein Flüchtigkeitsfehler unterlaufen.

                      Kommentar


                      • #26
                        bind_param finde ich sowieso ein sehr unübersichtliches Prinzip.
                        --

                        „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                        Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                        --

                        Kommentar


                        • #27
                          __get kann allerdings Referenzen zurückgeben, was übrigens ebenfalls in den Kommentaren in der Doku steht.

                          PHP-Code:
                          <?php

                          class Foo
                          {
                              protected 
                          $bar = array('d''b''a''c');

                              public function &
                          __get($name)
                              {
                                  if (
                          $name === 'bar') {
                                      return 
                          $this->bar;
                                  }

                                  throw new 
                          Exception('');
                              }
                          }

                          error_reporting(-1);

                          $foo = new Foo();

                          sort($foo->bar);

                          print_r($foo->bar);
                          Das fühlt sich dennoch etwas seltsam an.

                          Kommentar


                          • #28
                            Zitat von nikosch Beitrag anzeigen
                            bind_param finde ich sowieso ein sehr unübersichtliches Prinzip.
                            Ja stimmt schon. Ich nutze das irgendwie aus Gewohnheit noch meistens. Wird aber wohl langsam mal Zeit mir PDO und dann auch mal Doctrine2 reinzuziehen.


                            Zitat von mermshaus Beitrag anzeigen
                            __get kann allerdings Referenzen zurückgeben, was übrigens ebenfalls in den Kommentaren in der Doku steht.

                            PHP-Code:
                            <?php

                            class Foo
                            {
                                protected 
                            $bar = array('d''b''a''c');

                                public function &
                            __get($name)
                                {
                                    if (
                            $name === 'bar') {
                                        return 
                            $this->bar;
                                    }

                                    throw new 
                            Exception('');
                                }
                            }

                            error_reporting(-1);

                            $foo = new Foo();

                            sort($foo->bar);

                            print_r($foo->bar);
                            Das fühlt sich dennoch etwas seltsam an.
                            Ja stimmt, mit &__get wird auch bei meinem Beispiel "Hallo Welt!" und "Und tschüß" eingetragen. Geht mir aber wie dir, fühlt sich etwas seltsam an, ich kann aber nicht genau sagen wieso.
                            Hatte bei den Comments wohl nicht weit genug runtergescrollt, bzw den Beitrag irgendwie übersehen. Wobei das eigentlich auch recht naheliegend ist.

                            Kommentar


                            • #29
                              Habe einige Tests gemacht, weil ich in der Doku nichts dazu gefunden habe:

                              PHP-Code:
                              <?php

                              error_reporting
                              (-1);


                              // Geht

                              class Foo
                              {
                                  public function &
                              bar() {}
                              }

                              class 
                              FooChild extends Foo
                              {
                                  protected 
                              $bar 'bar';
                                  public function 
                              bar() { return $this->bar; }
                              }

                              $fc = new FooChild();
                              echo 
                              $fc->bar();



                              // Geht

                              class Foo2
                              {
                                  public function 
                              bar() {}
                              }

                              class 
                              Foo2Child extends Foo
                              {
                                  protected 
                              $bar 'bar';
                                  public function &
                              bar() { return $this->bar; }
                              }

                              $fc = new Foo2Child();
                              echo 
                              $fc->bar();



                              // Fatal error: Declaration of Foo3Child::bar() must be compatible with that of 
                              // Foo3::bar()

                              abstract class Foo3
                              {
                                  abstract public function &
                              bar();
                              }

                              class 
                              Foo3Child extends Foo3
                              {
                                  protected 
                              $bar 'bar';
                                  public function 
                              bar() { return $this->bar; }
                              }

                              $fc = new Foo3Child();
                              echo 
                              $fc->bar();



                              // Geht

                              abstract class Foo4
                              {
                                  abstract public function 
                              bar();
                              }

                              class 
                              Foo4Child extends Foo4
                              {
                                  protected 
                              $bar 'bar';
                                  public function &
                              bar() { return $this->bar; }
                              }

                              $fc = new Foo4Child();
                              echo 
                              $fc->bar();

                              Kommentar

                              Lädt...
                              X