Was sind die Vorteile der Verwendung von Gettern und Settern anstelle von Funktionen oder einfach öffentlichen Feldern in PHP? [closed]
Lesezeit: 10 Minuten
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
<?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?
SkalierbarkeitHinweis: Es ist einfacher, einen Getter umzugestalten, als alle Var-Zuweisungen in einem Projektcode zu durchsuchen.
Debuggen: Sie können Haltepunkte bei Settern und Gettern setzen.
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.
Wenn Sie @property verwenden, schlägt Ihre IDE den Code vor (getestet mit PhpStorm 7)
– Alex2php
13. Dezember 2013 um 19:46 Uhr
Magallanen
Google hat bereits einen Leitfaden zur Optimierung von PHP veröffentlicht und das Fazit war:
Und nein, du musst keine magischen Methoden anwenden. Für PHP sind Magic Methods böse. Wieso den?
Sie sind schwer zu debuggen.
Es gibt negative Auswirkungen auf die Leistung.
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.
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
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
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
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
13619600cookie-checkWas sind die Vorteile der Verwendung von Gettern und Settern anstelle von Funktionen oder einfach öffentlichen Feldern in PHP? [closed]yes
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