Was sind die Vorteile der Verwendung von Gettern und Settern anstelle von Funktionen oder einfach öffentlichen Feldern in PHP? [closed]

Lesezeit: 10 Minuten

Benutzer-Avatar
Markieren

Ich bin kein PHP-Entwickler, daher frage ich mich, welche Vor- und Nachteile in PHP die Verwendung expliziter Getter/Setter in einem reinen OOP-Stil mit privaten Feldern hat (so wie ich es mag):

class MyClass {
    private $firstField;
    private $secondField;

    public function getFirstField() {
        return $this->firstField;
    }
    public function setFirstField($x) {
        $this->firstField = $x;
    }
    public function getSecondField() {
        return $this->secondField;
    }
    public function setSecondField($x) {
        $this->secondField = $x;
    }
}

oder nur öffentliche Felder:

class MyClass {
    public $firstField;
    public $secondField;
}

  • PHPstorm… generieren > Getter und Setter. == gewinnen

    – DevDonkey

    14. Juli 2015 um 13:46 Uhr


  • @DevDonkey Überhaupt kein Gewinn. Verwenden Sie zum Halten strukturierter Daten stattdessen Arrays. @:Mark Das ist nicht das, was Objekte sind oder wofür sie da sind. Getter und Setter sind böse: yegor256.com/2014/09/16/getters-and-setters-are-evil.html

    – Kubo2

    17. Januar 2020 um 11:31 Uhr


Benutzer-Avatar
Davis Peixoto

Sie können verwenden php magische Methoden __get und __set.

<?php
class MyClass {
  private $firstField;
  private $secondField;

  public function __get($property) {
    if (property_exists($this, $property)) {
      return $this->$property;
    }
  }

  public function __set($property, $value) {
    if (property_exists($this, $property)) {
      $this->$property = $value;
    }

    return $this;
  }
}
?>

  • Was ist der Vorteil dagegen public Eigenschaften, wenn es keine Validierung/Sanierung gibt?

    – KingCrunch

    14. Mai 2011 um 0:06 Uhr

  • @KingCrunch, das ist nur ein Beispiel. Ein sehr sehr Dummy-Beispiel für eine mächtige Ressource.

    – Davis Peixoto

    19. Mai 2011 um 1:07 Uhr

  • Das ist nicht wirklich Setter und Getter. Normalerweise brauche ich für jede Eigenschaft eine andere Implementierung von Getter!

    – Summe

    16. Februar 2013 um 0:59 Uhr

  • Bitte nicht: Mit magischen Methoden verlieren Sie fast alle qualitätsbezogenen Funktionen in vielen IDEs (sogar vim): automatische Vervollständigung, explizite PHP-Vererbung, schnelle PHP-Interpretation und nützliche PHPDoc-Generierung und -Ausgabe. vgl. stackoverflow.com/a/6184893/490589

    – Ronan

    1. Juli 2013 um 20:33 Uhr

  • Bitte beziehen Sie sich auf diesen Beitrag und die gewählte Antwort stackoverflow.com/questions/4713680/…. __Get und __Set sind nicht richtig zu verwenden, sie dienen der Fehlerbehandlung!

    – allencodiert

    25. September 2014 um 0:01 Uhr

Warum Getter und Setter verwenden?

  1. SkalierbarkeitHinweis: Es ist einfacher, einen Getter umzugestalten, als alle Var-Zuweisungen in einem Projektcode zu durchsuchen.
  2. Debuggen: Sie können Haltepunkte bei Settern und Gettern setzen.
  3. Reiniger: Magische Funktionen sind keine gute Lösung, um weniger zu schreiben, Ihre IDE schlägt den Code nicht vor. Verwenden Sie besser Vorlagen für schnell schreibende Getter.

direkte Zuweisung und Getter/Setter

  • Wenn Sie @property verwenden, schlägt Ihre IDE den Code vor (getestet mit PhpStorm 7)

    – Alex2php

    13. Dezember 2013 um 19:46 Uhr

Benutzer-Avatar
Magallanen

Google hat bereits einen Leitfaden zur Optimierung von PHP veröffentlicht und das Fazit war:

Kein Getter und Setter PHP optimieren

Und nein, du musst keine magischen Methoden anwenden. Für PHP sind Magic Methods böse. Wieso den?

  1. Sie sind schwer zu debuggen.
  2. Es gibt negative Auswirkungen auf die Leistung.
  3. Sie erfordern das Schreiben von mehr Code.

PHP ist nicht Java, C++ oder C#. PHP ist anders und spielt mit anderen Regeln.

  • Ich neige dazu, dieser Idee zuzustimmen; das $dog->name = 'fido' ist besser als $dog->setName('fido'). Beim tatsächlichen Mutieren einer Eigenschaft (z. B.: $dog->increaseAge(1) Ich kann die Methode entwickeln, die die notwendige Validierung durchführt und diese Eigenschaft mutiert. Aber nicht alle Handlungen erfordern wirklich eine Mutation in diesem Sinne.

    – Charlie Schliesser

    23. Juni 2013 um 6:37 Uhr


  • Der Artikel nicht sagen “nicht“, heißt es „naive Setter und Getter“.

    – Brett Santore

    24. Juli 2014 um 18:55 Uhr


  • Man kann davon ausgehen, dass ein von Google geschriebener Artikel mit der Überschrift „PHP-Leistungstipps“ NICHT einen guten Programmierstil vorschlagen soll, sondern eine schnelle Codeausführung. Das Kapitel, das sich mit Settern und Gettern befasst, trägt die Überschrift „Vermeiden Sie, naive Setter und Getter zu schreiben“, und das Codebeispiel ist genau das: Naiv. Es setzt und erhält nur eine Variable ohne Validierung. Diese Art von Setter/Getter ist nutzlos. Durch die Validierung innerhalb eines Setters (verwenden Sie einfach einen Typhinweis für das Methodenargument) werden Setter/Getter nützlich, da Ihr Code jetzt weiß, womit er es zu tun hat.

    – Sven

    22. August 2016 um 12:23 Uhr

  • Das ist, als würde man sagen, dass Inline-Styling besser ist. Natürlich ist die Leistung besser, aber ist es besserer Code? Ich wusste sowieso nicht, dass Google-Ingenieure PHP verwenden

    – Claudius Creanga

    8. September 2016 um 14:03 Uhr

  • Dabei fehlen einige Dinge. Es stimmt zwar, dass Sie nicht naiv sein sollten (machen Sie alles zu Settern/Gettern), aber das gilt auch für die anderen Sprachen. $obj->var = $wert; macht Sinn, aber es SOLLTE bei der Ausführung in $obj-setVar($value) übersetzt werden. Nicht nur das, die Leute scheinen auch davon auszugehen, dass alle Eigenschaften lesbar/schreibbar sein sollten und dass sie NICHTS anderes beeinflussen. Zum Beispiel bevorzuge ich $obj->name, aber wenn ich möchte, dass es schreibgeschützt ist, muss ich es zu einer Funktion $obj->getName(); machen. $name = $obj->name sollte funktionieren, aber $obj->name = $var sollte fehlschlagen.

    – Rahly

    23. August 2017 um 23:32 Uhr


Kapselung ist in jeder OO-Sprache wichtig, Popularität hat damit nichts zu tun. In dynamisch typisierten Sprachen wie PHP ist dies besonders nützlich, da es nur wenige Möglichkeiten gibt, sicherzustellen, dass eine Eigenschaft von einem bestimmten Typ ist, ohne Setter zu verwenden.

In PHP funktioniert das:

class Foo {
   public $bar; // should be an integer
}
$foo = new Foo;
$foo->bar = "string";

In Java nicht:

class Foo {
   public int bar;
}
Foo myFoo = new Foo();
myFoo.bar = "string"; // error

Mit magischen Methoden (__get und __set) funktioniert auch, aber nur, wenn auf eine Eigenschaft zugegriffen wird, die eine geringere Sichtbarkeit hat, als der aktuelle Bereich darauf zugreifen kann. Es kann Ihnen beim Debuggen leicht Kopfschmerzen bereiten, wenn es nicht richtig verwendet wird.

Benutzer-Avatar
J-Rou

Wenn Sie die __call-Funktion bevorzugen, können Sie diese Methode verwenden. Es funktioniert mit

  • ERHALTEN => $this->property()
  • EINSTELLEN => $this->property($value)
  • ERHALTEN => $this->getProperty()
  • EINSTELLEN => $this->setProperty($value)

kalsdas

public function __call($name, $arguments) {

    //Getting and setting with $this->property($optional);

    if (property_exists(get_class($this), $name)) {


        //Always set the value if a parameter is passed
        if (count($arguments) == 1) {
            /* set */
            $this->$name = $arguments[0];
        } else if (count($arguments) > 1) {
            throw new \Exception("Setter for $name only accepts one parameter.");
        }

        //Always return the value (Even on the set)
        return $this->$name;
    }

    //If it doesn't chech if its a normal old type setter ot getter
    //Getting and setting with $this->getProperty($optional);
    //Getting and setting with $this->setProperty($optional);
    $prefix = substr($name, 0, 3);
    $property = strtolower($name[3]) . substr($name, 4);
    switch ($prefix) {
        case 'get':
            return $this->$property;
            break;
        case 'set':
            //Always set the value if a parameter is passed
            if (count($arguments) != 1) {
                throw new \Exception("Setter for $name requires exactly one parameter.");
            }
            $this->$property = $arguments[0];
            //Always return the value (Even on the set)
            return $this->$name;
        default:
            throw new \Exception("Property $name doesn't exist.");
            break;
    }
}

  • @krzysztof-przygoda: Diese „magischen Methoden“ haben immer ihren Preis. Sie müssen Rekursion verwenden property_exists(get_class($this), $name) und die Rekursion ist langsam. Es gibt eine Möglichkeit, dies durch Caching abzumildern, aber es wird immer noch langsamer sein, als die Getter und Setter von Hand zu erstellen. Ich habe das nur als Alternative geschrieben. Ich empfehle eigentlich nicht, “magische Methoden” zu verwenden. Die zusätzliche Zeit zum Erstellen der Getter und Setter ist normalerweise unbedeutend.

    – J-Rou

    18. Dezember 2015 um 13:24 Uhr

Benutzer-Avatar
Gemeinschaft

Zusätzlich zu den bereits großartigen und respektierten Antworten hier möchte ich auf PHP eingehen, das keine Setter/Getter hat.

PHP hat keine Getter- und Setter-Syntax. Es bietet Unterklassen oder Magie Methoden, um das “Hooking” und Überschreiben des Eigenschaftssuchprozesses zu ermöglichen, wie von aufgezeigt David.

Magie erlaubt wir faulen Programmierer mehr mit weniger Code zu einem Zeitpunkt zu erreichen, an dem wir aktiv an einem Projekt beteiligt sind und es genau kennen, aber normalerweise auf Kosten der Lesbarkeit.

Leistung Jede unnötige Funktion, die aus dem Erzwingen einer Getter/Setter-ähnlichen Code-Architektur in PHP resultiert, beinhaltet beim Aufruf einen eigenen Speicher-Stack-Frame und verschwendet CPU-Zyklen.

Lesbarkeit: Die Codebasis verursacht aufgeblähte Codezeilen, was sich auf die Codenavigation auswirkt, da mehr LOC mehr Scrollen bedeutet.

Präferenz: Persönlich nehme ich als Faustregel das Scheitern der statischen Codeanalyse als Zeichen dafür, den magischen Weg nicht zu beschreiten, solange mir zu diesem Zeitpunkt offensichtliche langfristige Vorteile entgehen.

Irrtümer:

Ein häufiges Argument ist die Lesbarkeit. Zum Beispiel das $someobject->width ist leichter zu lesen als $someobject->width(). Allerdings anders als bei einem Planeten circumference oder widthwovon ausgegangen werden kann staticdie Instanz eines Objekts wie z $someobjectdie eine Breitenfunktion erfordert, misst wahrscheinlich die Instanzbreite des Objekts.
Daher erhöht sich die Lesbarkeit hauptsächlich durch durchsetzungsfähige Benennungsschemata und nicht durch das Verstecken der Funktion, die einen bestimmten Eigenschaftswert ausgibt.

__get / __set verwendet:

  • Vorvalidierung und Vorsanierung von Immobilienwerten

  • Saiten zB

    "
    some {mathsobj1->generatelatex} multi
    line text {mathsobj1->latexoutput}
    with lots of variables for {mathsobj1->generatelatex}
     some reason
    "
    

    In diesem Fall generatelatex würde sich an ein Namensschema von Aktionsname + Methodenname halten

  • besondere, offensichtliche Fälle

    $dnastringobj->homeobox($one_rememberable_parameter)->gattaca->findrelated()
    $dnastringobj->homeobox($one_rememberable_parameter)->gttccaatttga->findrelated()
    

Notiz: PHP hat sich entschieden, keine Getter/Setter-Syntax zu implementieren. Ich behaupte nicht, dass Getter/Setter generell schlecht sind.

  • @krzysztof-przygoda: Diese „magischen Methoden“ haben immer ihren Preis. Sie müssen Rekursion verwenden property_exists(get_class($this), $name) und die Rekursion ist langsam. Es gibt eine Möglichkeit, dies durch Caching abzumildern, aber es wird immer noch langsamer sein, als die Getter und Setter von Hand zu erstellen. Ich habe das nur als Alternative geschrieben. Ich empfehle eigentlich nicht, “magische Methoden” zu verwenden. Die zusätzliche Zeit zum Erstellen der Getter und Setter ist normalerweise unbedeutend.

    – J-Rou

    18. Dezember 2015 um 13:24 Uhr

Benutzer-Avatar
Joas

class MyClass {
    private $firstField;
    private $secondField;
    private $thirdField;

    public function __get( $name ) {
        if( method_exists( $this , $method = ( 'get' . ucfirst( $name  ) ) ) )
            return $this->$method();
        else
            throw new Exception( 'Can\'t get property ' . $name );
    }

    public function __set( $name , $value ) {
        if( method_exists( $this , $method = ( 'set' . ucfirst( $name  ) ) ) )
            return $this->$method( $value );
        else
            throw new Exception( 'Can\'t set property ' . $name );
    }

    public function __isset( $name )
    {
        return method_exists( $this , 'get' . ucfirst( $name  ) ) 
            || method_exists( $this , 'set' . ucfirst( $name  ) );
    }

    public function getFirstField() {
        return $this->firstField;
    }

    protected function setFirstField($x) {
        $this->firstField = $x;
    }

    private function getSecondField() {
        return $this->secondField;
    }
}

$obj = new MyClass();

echo $obj->firstField; // works
$obj->firstField = 'value'; // works

echo $obj->getFirstField(); // works
$obj->setFirstField( 'value' ); // not works, method is protected

echo $obj->secondField; // works
echo $obj->getSecondField(); // not works, method is private

$obj->secondField = 'value'; // not works, setter not exists

echo $obj->thirdField; // not works, property not exists

isset( $obj->firstField ); // returns true
isset( $obj->secondField ); // returns true
isset( $obj->thirdField ); // returns false

Bereit!

  • Zu viel Boilerplate. Stellen Sie sich vor, dieses Zeug wäre in jeder Klasse. Vermeiden Sie IMO

    – DarkNeuron

    9. Dezember 2015 um 13:35 Uhr

  • PHP unterstützt aus den von Ihnen genannten Gründen keine Getter und Setter. Jede Implementierung dieses Typs wirkt sich stark auf die Leistung von serverseitigem Skript aus.

    – joas

    20. Februar 2016 um 9:24 Uhr

  • Ich denke, das geht gegen “private” Eigenschaften. Sie kapseln sie, erlauben aber auch den direkten Zugriff.

    – Koray Küpe

    18. März 2019 um 15:44 Uhr

  • @KorayKüpe nur wenn der Getter definiert ist. Ich verwende diese Kapselung häufig (mit vielen Verbesserungen) und sie funktioniert perfekt. Sie können die Klasse auch erweitern und problemlos im gesamten Code verwenden.

    – joas

    9. April 2019 um 0:14 Uhr

1361960cookie-checkWas sind die Vorteile der Verwendung von Gettern und Settern anstelle von Funktionen oder einfach öffentlichen Feldern in PHP? [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy