Es sei denn , ich völlig täuscht, die __get
und __set
werden Verfahren soll ermöglichen , von der Überlastung → get
und set
.
Die folgenden Anweisungen sollten beispielsweise die __get
Methode aufrufen :
echo $foo->bar;
$var = $foo->bar;
Und die folgenden sollten die __set
Methode verwenden:
$foo->bar = 'test';
Dies funktionierte in meinem Code nicht und ist mit diesem einfachen Beispiel reproduzierbar:
class foo {
public $bar;
public function __get($name) {
echo "Get:$name";
return $this->$name;
}
public function __set($name, $value) {
echo "Set:$name to $value";
$this->$name = $value;
}
}
$foo = new foo();
echo $foo->bar;
$foo->bar = 'test';
echo "[$foo->bar]";
Dies führt nur zu:
[test]
Wenn Sie dort einige die()
Anrufe tätigen, wird angezeigt, dass es überhaupt nicht funktioniert.
Im Moment habe ich nur gesagt, scheiß drauf und verwende manuell, __get
wo es jetzt gebraucht wird, aber das ist nicht sehr dynamisch und erfordert das Wissen, dass der "überladene" Code tatsächlich nicht aufgerufen wird, es sei denn, er wird speziell aufgerufen. Ich würde gerne wissen, ob dies entweder nicht so funktionieren soll, wie ich es verstanden habe, oder warum dies nicht funktioniert.
Das läuft weiter php 5.3.3
.
quelle
node
es keine Eigenschaft von $ foo ist, sondern eine Eigenschaft vondoesNotExist
. Solange 'doesNotExist' kein Objekt ist (das __set implementiert oder eine öffentliche Eigenschaft namens node hat), funktioniert es nicht.Ich würde empfehlen, ein Array zum Speichern aller Werte über zu verwenden
__set()
.Auf diese Weise stellen Sie sicher, dass Sie nicht auf andere Weise auf die Variablen zugreifen können (Hinweis, der
$values
geschützt ist), um Kollisionen zu vermeiden.quelle
Aus dem PHP-Handbuch :
Dies wird nur beim Lesen / Schreiben unzugänglicher Eigenschaften aufgerufen . Ihr Eigentum ist jedoch öffentlich, was bedeutet, dass es zugänglich ist. Durch Ändern des Zugriffsmodifikators in "Geschützt" wird das Problem behoben.
quelle
Um Berrys Antwort zu erweitern: Wenn Sie die Zugriffsebene auf "Geschützt" setzen, können __get und __set mit explizit deklarierten Eigenschaften verwendet werden (zumindest beim Zugriff außerhalb der Klasse). Da die Geschwindigkeit erheblich langsamer ist, zitiere ich einen Kommentar aus einer anderen Frage zu diesem Thema und begründen Sie es trotzdem:
Ich bin damit einverstanden, dass __get für eine benutzerdefinierte Get-Funktion langsamer ist (die gleichen Aktionen ausführt). Dies ist 0,0124455 für __get () und 0,0024445 für benutzerdefinierte get () nach 10000 Schleifen. - Melsi 23. November 12 um 22:32 Best Practice: PHP Magic Methoden __set und __get
Nach Melsis Tests ist erheblich langsamer etwa fünfmal langsamer. Das ist definitiv erheblich langsamer, aber beachten Sie auch, dass die Tests zeigen, dass Sie mit dieser Methode immer noch 10.000 Mal auf eine Eigenschaft zugreifen können, wobei die Zeit für die Schleifeniteration in ungefähr 1/100 Sekunde gezählt wird. Es ist im Vergleich zu den tatsächlich definierten Get- und Set-Methoden erheblich langsamer, und das ist eine Untertreibung, aber im großen Schema der Dinge ist sogar fünfmal langsamer nie wirklich langsam.
Die Rechenzeit des Vorgangs ist immer noch vernachlässigbar und in 99% der realen Anwendungen nicht zu berücksichtigen. Das einzige Mal, dass es wirklich vermieden werden sollte, ist, wenn Sie in einer einzigen Anfrage mehr als 10.000 Mal auf die Eigenschaften zugreifen. Websites mit hohem Datenverkehr machen etwas wirklich Falsches, wenn sie es sich nicht leisten können, ein paar weitere Server hochzuwerfen, um ihre Anwendungen am Laufen zu halten. Eine einzeilige Textanzeige in der Fußzeile einer stark frequentierten Site, bei der die Zugriffsrate zum Problem wird, könnte wahrscheinlich für eine Farm mit 1.000 Servern mit dieser Textzeile bezahlt werden. Der Endbenutzer wird niemals mit den Fingern tippen und sich fragen, was das Laden der Seite so lange dauert, da der Zugriff auf die Eigenschaften Ihrer Anwendung eine Millionstel Sekunde dauert.
Ich sage dies als Entwickler mit einem Hintergrund in .NET, aber unsichtbare Methoden zum Abrufen und Festlegen für den Verbraucher sind keine Erfindung von .NET. Sie sind einfach keine Eigenschaften ohne sie, und diese magischen Methoden sind die Rettung des PHP-Entwicklers, wenn es darum geht, ihre Version von Eigenschaften überhaupt als "Eigenschaften" zu bezeichnen. Außerdem unterstützt die Visual Studio-Erweiterung für PHP Intellisense mit geschützten Eigenschaften, mit diesem Trick, denke ich. Ich würde denken, wenn genügend Entwickler die magischen Methoden __get und __set auf diese Weise verwenden, würden die PHP-Entwickler die Ausführungszeit optimieren, um der Entwicklergemeinschaft gerecht zu werden.
Bearbeiten: Theoretisch schienen geschützte Eigenschaften in den meisten Situationen zu funktionieren. In der Praxis stellt sich heraus, dass Sie häufig Ihre Getter und Setter verwenden möchten, wenn Sie auf Eigenschaften innerhalb der Klassendefinition und der erweiterten Klassen zugreifen. Eine bessere Lösung ist eine Basisklasse und eine Schnittstelle für die Erweiterung anderer Klassen, sodass Sie nur die wenigen Codezeilen aus der Basisklasse in die implementierende Klasse kopieren können. Ich mache ein bisschen mehr mit der Basisklasse meines Projekts, daher muss ich momentan keine Schnittstelle bereitstellen, aber hier ist die ungetestete, reduzierte Klassendefinition mit dem Abrufen und Festlegen magischer Eigenschaften mithilfe von Reflektion zum Entfernen und Verschieben der Eigenschaften ein geschütztes Array:
Ich entschuldige mich, wenn der Code Fehler enthält.
quelle
Es ist, weil $ bar ein öffentliches Eigentum ist.
Es ist nicht erforderlich, die magische Methode aufzurufen, wenn Sie die oben genannten Schritte ausführen.
Das Löschen
public $bar;
aus Ihrer Klasse sollte dies korrigieren.quelle
Verwenden Sie am besten magische Set / Get-Methoden mit vordefinierten benutzerdefinierten Set / Get-Methoden wie im folgenden Beispiel. Auf diese Weise können Sie das Beste aus zwei Welten kombinieren. In Bezug auf die Geschwindigkeit stimme ich zu, dass sie etwas langsamer sind, aber spürt man sogar den Unterschied. Das folgende Beispiel überprüft das Datenarray auch anhand vordefinierter Setter.
Deshalb sollten wir beide verwenden.
BEISPIEL EINER KLASSE
INDEX.PHP
AUSGABE
quelle
Löschen Sie die
public $bar;
Deklaration und es sollte wie erwartet funktionieren.quelle
Intenta con:
quelle