wie man eine PHP-Klasse erstellt, die in Boolean umgewandelt werden kann (truthy oder falsy)

7

Ich erstelle eine Collection-Klasse und möchte sie als Ersatz für Arrays verwenden, die ich momentan verwende.

Wie erstelle ich eine Klasse, die in Boolean umgewandelt werden kann, so dass die Klasse truthy oder falsy sein kann?

Ein einfacher Test zeigt, dass ein Objekt der leeren Klasse truthig ist:

%Vor%

Aber ich muss entscheiden, ob meine Klasse truthy oder falsy ist. Gibt es eine Möglichkeit, der PHP-Engine zu sagen, wie ich meine Klasse auf Boolean umwandeln soll? Wie könnte ich mit __toString () tun?

Hintergrund:

Sagen wir, ich schreibe eine Klasse wie diese (es ist nur ein Beispiel):

%Vor%

Ich benutze dieses Muster derzeit sehr:

%Vor%

Ich möchte das so aussehen:

%Vor%

und den Rest unverändert lassen. Aber das $ var, das MyCollection enthält, ist immer truthy, also würde ich alle Bedingungen benötigen, um:

%Vor%

Aber das ist inakzeptabel, da meine Codebasis viele Megabyte hat.

Irgendeine Lösung hier?

    
SWilk 24.05.2011, 16:06
quelle

6 Antworten

6

Auf dieser Seite werden die magischen Methoden aufgelistet, die Sie für Ihre Klassen definieren können.

Ссылка

Sie zeigen, dass Sie bereits von __toString() wissen.

Leider gibt es dort keine magische Methode, die das tut, was du verlangst. Also, ich denke für jetzt ist Ihre einzige Option, eine Methode zu definieren und diese Methode explizit aufzurufen.

    
Hammerite 24.05.2011, 16:14
quelle
19

Nach vielen Ängsten, Enttäuschungen und Hackern - ich glaube, ich habe eine Lösung gefunden. Die Lösung erfordert keine Erweiterungen; Es kann mit einer sehr kleinen Menge von PHP-Boilerplate implementiert werden. Bevor Sie diese Lösung jedoch selbst implementieren, beachten Sie bitte, dass dies in der Tat ein RIESIGER Hack ist. Davon abgesehen, hier ist, was ich entdeckt habe:

Frustriert habe ich einige Zeit damit verbracht, über die PHP-Dokumentation für Booleans zu schauen . Während benutzergenerierten Klassen einfach die Möglichkeit verwehrt wird, als Boolean zu wirken, wurde eine Klasse - seltsam genug - die Fähigkeit gewährt. Der schlaue Leser würde bemerken, dass diese Klasse nichts anderes als das eingebaute SimpleXmlElement ist. Durch den Deduktionsprozess scheint es fair anzunehmen, dass jede Unterklasse von SimpleXmlElement auch ihre einzigartige boolesche Casting-Fähigkeit erben würde. Während dieser Ansatz in der Theorie gültig zu sein scheint, entzieht die Magie, die SimpleXmlElement umgibt, auch die Nützlichkeit dieses Ansatzes. Um dies zu verstehen, betrachten Sie dieses Beispiel:

%Vor%

Truthy ist eine Unterklasse von SimpleXmlElement, daher sollten wir testen können, ob seine spezielle boolesche Casting-Eigenschaft geerbt wurde:

%Vor%

Tatsächlich wird die boolesche Casting-Eigenschaft von SimpleXmlElement von Truthy geerbt. Diese Syntax ist jedoch plump und es ist höchst unwahrscheinlich, dass man aus dieser Klasse viel Nutzen ziehen könnte (zumindest im Vergleich zur nativen Verwendung von SimpleXmlElement). In diesem Szenario beginnen die Probleme:

%Vor%

Wie Sie sehen können, bricht der Versuch, eine Eigenschaft in unserer Unterklasse zu setzen, sofort das Dienstprogramm, das wir vom geerbten booleschen Casting erhalten. Leider hat das SimpleXmlElement eine weitere magische Eigenschaft, die unsere Konvention bricht. Wenn Sie eine Eigenschaft eines SimpleXmlElement festlegen, ändert es anscheinend das XML! Überzeugen Sie sich selbst:

%Vor%

Nun, es geht jedes Dienstprogramm, das wir von Subclassing SimpleXmlElement bekommen würden! Zum Glück habe ich nach vielem Hacken einen Weg gefunden, Informationen in diese Unterklasse zu speichern, ohne die boolesche Zauberwirkung zu brechen: Kommentare!

%Vor%

Fortschritt! Wir konnten nützliche Informationen in diese Klasse bringen, ohne das Boolesche Casting zu unterbrechen! Ok, jetzt müssen wir nur noch aufräumen, hier ist meine letzte Implementierung:

%Vor%

Um etwas von der Ungeschicklichkeit zu entfernen, habe ich eine öffentliche statische Factory-Methode hinzugefügt. Jetzt können wir ein Truthy-Objekt erstellen, ohne uns um die Implementierungsdetails kümmern zu müssen. Die Factory lässt den Aufrufer beliebige Datenmengen sowie ein boolesches Casting definieren. Die Datenmethode kann dann zu einem späteren Zeitpunkt aufgerufen werden, um eine schreibgeschützte Kopie dieser Daten abzurufen:

%Vor%

Da hast du es! Eine völlig hackige (aber brauchbare) Möglichkeit, boolesche Castings in benutzerdefinierten Klassen durchzuführen. Bitte verklagen Sie mich nicht, wenn Sie dies im Produktionscode verwenden und es explodiert.

    
Jonathan Azoff 15.01.2013 01:29
quelle
4

Sie können sich die PHP Operator-Erweiterung ansehen, mit der Sie viele Operatoren einschließlich == und = überladen können ==. Mit dieser Erweiterung sollten Sie theoretisch in der Lage sein, eine Klasse zu schreiben, die mit booleschen Werten vergleichbar ist:

%Vor%     
Smasty 24.05.2011 16:27
quelle
1

Sie können nicht.

In PHP erzeugt ein Objekt, wenn es in bool umgewandelt wird, immer true . Das kann man nicht ändern.

    
vartec 24.05.2011 16:17
quelle
0

Wenn Sie eine Code-Größe von "vielen Megabyte" haben, ist das Problem wahrscheinlich nicht, dass Ihr Benennungsschema zu ausführlich ist. Ich würde stattdessen nach Doppelarbeit suchen und versuchen, Code zu abstrahieren.

OTOH, warum ist die Größe des Codes ein großes Problem? Versuchen Sie, den Code zu minimieren, den Sie bei jeder Ausführung von PHP einbeziehen. Streucode, der nicht verwendet wird, macht keinen Unterschied. Wenn Sie einen sehr hohen Code verwenden möchten, sollten Sie Caching-Software wie MMCache verwenden.

Und um Ihre ursprüngliche Frage, AFAIK, zu beantworten, gibt es keine Möglichkeit, den PHP-Klassen Typenzwang hinzuzufügen. Eine Instanz wird immer als wahr ausgewertet.

    
Adam Bergmark 24.05.2011 16:11
quelle
0

Wenn du deine eigene Methode nicht implementieren willst, kannst du dich in __toString hineinhacken, wie folgt:

%Vor%     
Alix Axel 24.05.2011 17:11
quelle

Tags und Links