Ich werde etwas mit dem Format dieser Frage versuchen, und ich bin sehr offen für Vorschläge über einen besseren Weg, damit umzugehen.
Ich wollte nicht einfach einen Haufen Code in der Frage ablegen, also habe ich den Code für die Klasse unter refactormycode veröffentlicht.
Basisklasse für die einfache Handhabung von Klasseneigenschaften
Mein Gedanke war, dass Leute hier entweder Codeschnipsel posten oder Änderungen an refactormycode vornehmen und Links zu ihren Refactorings zurücksenden können. Ich werde Upvotes machen und eine Antwort akzeptieren (vorausgesetzt es gibt einen klaren "Gewinner"), basierend darauf.
Jedenfalls auf die Klasse selbst:
Ich sehe viele Diskussionen über Getter / Setter-Klassenmethoden und ist es besser, einfach nur auf einfache Eigenschaftsvariablen zuzugreifen, oder sollte jede Klasse explizite get / set-Methoden haben, bla bla bla. Ich mag die Idee, explizite Methoden zu haben, falls Sie später mehr Logik hinzufügen müssen. Dann müssen Sie keinen Code ändern, der die Klasse verwendet. Aber ich hasse es, eine Million Funktionen zu haben, die so aussehen:
%Vor%Ich bin mir sicher, dass ich nicht die erste Person bin, die das tut (ich hoffe, dass es einen besseren Weg gibt, den mir jemand vorschlagen kann).
Grundsätzlich verfügt die PropertyHandler-Klasse über eine Call-Magic-Methode. Alle Methoden, die durch __call kommen und mit "get" oder "set" beginnen, werden dann an Funktionen weitergeleitet, die Werte in einem assoziativen Array setzen oder abrufen. Der Schlüssel in das Array ist der Name der aufrufenden Methode nach get oder set. Wenn also die Methode, die in __call eingeht, "getFirstName" lautet, lautet der Array-Schlüssel "FirstName".
Ich habe __call gerne benutzt, weil es sich automatisch um den Fall kümmert, in dem die Unterklasse bereits eine "getFirstName" -Methode definiert hat. Mein Eindruck (und ich könnte falsch liegen) ist, dass die __get & amp; __set magische Methoden tun das nicht.
Hier ist ein Beispiel, wie es funktionieren würde:
%Vor%Beachten Sie, dass PropTest nicht tatsächlich "setFirstName" - oder "getFirstName" -Methoden hat und auch PropertyHandler nicht. Es werden nur Array-Werte manipuliert.
Der andere Fall wäre, wo Ihre Unterklasse bereits etwas anderes erweitert. Da Sie in PHP keine echte Mehrfachvererbung haben können, können Sie Ihre Unterklasse dazu veranlassen, eine PropertyHandler-Instanz als private Variable zu verwenden. Sie müssen eine weitere Funktion hinzufügen, aber dann verhalten sich die Dinge genauso.
%Vor%Beachten Sie, dass die Unterklasse eine __call-Methode hat, die alles an die PropertyHandler __call-Methode weiterleitet.
Ein anderes gutes Argument gegen die Handhabung von Getter und Setter ist, dass es sehr schwer zu dokumentieren ist.
Tatsächlich ist es im Prinzip unmöglich, ein Dokumentgenerierungstool zu verwenden, da die expliziten Methoden, die nicht dokumentiert werden sollen, nicht existieren.
Ich habe diesen Ansatz vorerst aufgegeben. Es war eine interessante Lernübung, aber ich denke, es opfert zu viel Klarheit.
Mein Problem dabei ist, dass das Hinzufügen von "mehr Logik zu einem späteren Zeitpunkt" das Hinzufügen von pauschaler Logik für alle Eigenschaften erfordert, auf die mit dem Getter / Setter zugegriffen wird, oder die Sie verwenden, wenn Sie angeben, auf welche Eigenschaft Sie zugreifen Sie können eine bestimmte Logik anwenden.
Das stimmt nicht ganz. Nehmen Sie mein erstes Beispiel:
%Vor%Nehmen wir an, dass ich eine Logik für die Validierung von FirstNames hinzufügen muss. Alles, was ich tun muss, ist eine Methode setFirstName zu meiner Unterklasse hinzufügen und diese Methode wird stattdessen automatisch verwendet.
%Vor%Ich bin einfach nicht zufrieden mit den Einschränkungen, die PHP bei impliziten Zugriffsmethoden hat.
Ich stimme völlig zu. Ich mag die Python-Art, dies zu handhaben (meine Implementierung ist nur eine ungeschickte Abzocke davon).
Ich mag Methoden, anstatt nur öffentliche Felder zu verwenden, aber mein Problem mit der PHP-Standardimplementierung (mit __get () und __set ()) oder Ihrer benutzerdefinierten Implementierung besteht darin, dass Sie keine Getter und Setter auf a einrichten Pro-Objekt-Basis. Mein Problem dabei ist, dass das Hinzufügen von "mehr Logik später" erfordert, dass Sie pauschale Logik hinzufügen, die für alle Eigenschaften gilt, auf die mit dem Getter / Setter zugegriffen wird oder die Sie verwenden, wenn Sie Anweisungen ändern, um zu ermitteln, auf welche Eigenschaft Sie zugreifen spezifische Logik.
Ich mag Ihre Lösung, und ich applaudiere Ihnen dafür - ich bin einfach nicht zufrieden mit den Einschränkungen, die PHP hat, wenn es um implizite Zugriffsmethoden geht.
@Mark
Aber selbst Ihre Methode erfordert eine neue Deklaration der Methode, und sie hat den Vorteil, dass sie in eine Methode eingefügt werden kann, so dass Sie mehr Logik hinzufügen können, denn um mehr Logik hinzuzufügen, erfordert die altmodische Deklaration der Methode , sowieso. In ihrem Standardzustand (wo sie beeindruckend ist, was sie erkennt / tut), bietet Ihre Technik keinen Vorteil (in PHP) gegenüber öffentlichen Feldern. Sie beschränken den Zugriff auf das Feld, aber geben Carte Blanche durch Zugriffsmethoden, die keine eigenen Einschränkungen haben. Ich bin mir nicht bewusst, dass unkontrollierte explizite Accessoren einen Vorteil gegenüber öffentlichen Feldern in jeder Sprache bieten, aber die Leute können und sollten sich frei fühlen, mich zu korrigieren, wenn ich falsch liege.
Ich habe dieses Problem schon immer mit einem __call behandelt, der in vielen meiner Klassen so ziemlich mit einem Kesselblech-Code endet. Es ist jedoch kompakt und verwendet die Reflektionsklassen, um nur Getter / Setter für Eigenschaften hinzuzufügen, die Sie bereits festgelegt haben (es werden keine neuen hinzugefügt). Wenn Sie den Getter / Setter explizit hinzufügen, werden komplexere Funktionen hinzugefügt. Es wird erwartet,
zu seinCode sieht so aus:
%Vor%Hinzufügen zu einer Klasse, in der Sie Standardeigenschaften wie folgt deklariert haben:
%Vor%Die Reflexionsklasse kann Ihrem Vorschlag etwas hinzufügen. Saubere Lösung @Mark.
Vor Kurzem habe ich darüber nachgedacht, Getter und Setter so zu behandeln, wie Sie es vorgeschlagen haben (der zweite Ansatz war mein Favorit, dh das private $ reps-Array), aber ich habe es verworfen, weil es in meiner App nicht geklappt hätte.
Ich arbeite an einer ziemlich großen SoapServer-basierten Anwendung und die Soap-Schnittstelle von PHP 5 injiziert die Werte, die via Soap übertragen werden, direkt in die zugehörige Klasse, ohne sich um bestehende oder nicht existierende Eigenschaften in der Klasse zu kümmern. p>
Ich kann nicht helfen, meine 2 Cent hineinzulegen ...
Ich habe mich dafür entschieden, __get
und __set
in diesem Herrenhaus zu verwenden (ähnlich wie es die Doktrin tut) ), dann nur Zugriff auf die Eigenschaften über die $obj->var
außerhalb der Klasse. Auf diese Weise können Sie die Funktionalität nach Bedarf außer Kraft setzen, anstatt eine große Funktion __get
oder __set
zu erstellen oder __get
und __set
in den untergeordneten Klassen zu überschreiben.