Wie würde man eine Singleton-Klasse mit PHP5-Klassen erstellen?
php
oop
design-patterns
singleton
Andrew Moore
quelle
quelle
Antworten:
Benutzen:
$fact == $fact2;
Aber:
Wirft einen Fehler.
Unter http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static finden Sie Informationen zu statischen Variablenbereichen und warum die Einstellung
static $inst = null;
funktioniert.quelle
PHP 5.3 ermöglicht die Erstellung einer vererbbaren Singleton-Klasse durch späte statische Bindung:
Dies löst das Problem, dass vor PHP 5.3 jede Klasse, die einen Singleton erweitert hat, eine Instanz ihrer übergeordneten Klasse anstelle ihrer eigenen erzeugt.
Jetzt können Sie tun:
Und $ foo wird eine Instanz von Foobar anstelle einer Instanz von Singleton sein.
quelle
"subclass should own its own static var. check this: echo get_class(Foobar::getInstance());echo get_class(Singleton::getInstance());"
.$instance
befindet sich in Singleton, nicht in der Unterklasse. Nachdem eine Unterklasse instanziiert wurde, gibt getInstance () diese Instanz für alle Unterklassen zurück.Leider bricht die Antwort von Inwdr ab, wenn mehrere Unterklassen vorhanden sind.
Hier ist eine korrekte vererbbare Singleton-Basisklasse.
Testcode:
quelle
Die echte und moderne Art, Singleton-Muster zu erstellen, ist:
So, jetzt können Sie es wie verwenden.
Wie Sie sehen, ist diese Erkenntnis viel flexibler.
quelle
instance
Funktion$instance
solltenull
nicht seinfalse
Sie sollten wahrscheinlich eine private __clone () -Methode hinzufügen, um das Klonen einer Instanz zu verbieten.
Wenn Sie diese Methode nicht einschließen, ist Folgendes möglich
jetzt
$inst1
! ==$inst2
- sie sind nicht mehr dieselbe Instanz.quelle
benutzen:
Antwort:
Wenn Sie PHP 5.4 verwenden: Trait ist eine Option, sodass Sie die Vererbungshierarchie nicht verschwenden müssen, um das Singleton-Muster zu erhalten
Beachten Sie auch, dass unabhängig davon, ob Sie Merkmale verwenden oder die Singleton- Klasse erweitern, ein loses Ende darin bestand, ein Singleton untergeordneter Klassen zu erstellen, wenn Sie nicht die folgende Codezeile hinzufügen:
in der Kinderklasse
Das unerwartete Ergebnis wird sein:
quelle
Dieser Code kann für jede Klasse gelten, ohne sich um ihren Klassennamen zu kümmern.
quelle
Unterstützt mehrere Objekte mit 1 Zeile pro Klasse:
Diese Methode erzwingt Singletons für jede gewünschte Klasse. Sie müssen lediglich 1 Methode zu der Klasse hinzufügen, für die Sie einen Singleton erstellen möchten, und dies erledigt dies für Sie.
Dadurch werden auch Objekte in einer "SingleTonBase" -Klasse gespeichert, sodass Sie alle Ihre in Ihrem System verwendeten
SingleTonBase
Objekte durch Rekursion der Objekte debuggen können.Erstellen Sie eine Datei namens SingletonBase.php und fügen Sie sie in das Stammverzeichnis Ihres Skripts ein!
Der Code ist
Fügen Sie dann für jede Klasse, die Sie zu einem Singleton machen möchten, einfach diese kleine Einzelmethode hinzu.
Hier ist ein kleines Beispiel:
Sie können diese Singleton-Funktion einfach in jede Klasse einfügen und es wird nur 1 Instanz pro Klasse erstellt.
HINWEIS: Sie sollten das __construct immer privat machen, um die Verwendung der neuen Klasse () zu vermeiden. Instanziierungen.
quelle
quelle
Sie müssen das Singleton-Muster nicht wirklich verwenden, da es als Antimuster betrachtet wird. Grundsätzlich gibt es viele Gründe, dieses Muster überhaupt nicht zu implementieren. Lesen Sie dies zunächst: Best Practice für PHP-Singleton-Klassen .
Wenn Sie immer noch der Meinung sind, dass Sie das Singleton-Muster verwenden müssen, können wir eine Klasse schreiben, mit der wir die Singleton-Funktionalität erhalten, indem wir unsere abstrakte SingletonClassVendor-Klasse erweitern.
Dies ist, was ich kam, um dieses Problem zu lösen.
Anwendungsbeispiel:
Nur um zu beweisen, dass es wie erwartet funktioniert:
quelle
All diese Komplexität ("Late Static Binding" ... Harumph) ist für mich einfach ein Zeichen für das kaputte Objekt- / Klassenmodell von PHP. Wenn Klassenobjekte erstklassige Objekte waren (siehe Python), dann „$ _instance“ wäre eine Klasse Instanz Variable - ein Mitglied des Klassenobjekts, im Gegensatz zu einem Mitglied / Eigentum seiner Instanzen und auch im Gegensatz zu gemeinsamen von seinen Nachkommen. In der Smalltalk-Welt ist dies der Unterschied zwischen einer "Klassenvariablen" und einer "Klasseninstanzvariablen".
In PHP sieht es für mich so aus, als müssten wir uns die Anleitung zu Herzen nehmen, dass Muster eine Anleitung zum Schreiben von Code sind - wir denken vielleicht an eine Singleton-Vorlage, versuchen aber, Code zu schreiben, der von einer tatsächlichen "Singleton" -Klasse erbt sieht für PHP falsch aus (obwohl ich vermutete, dass eine unternehmungslustige Seele ein geeignetes SVN-Schlüsselwort erstellen könnte).
Ich werde weiterhin nur jeden Singleton einzeln mit einer gemeinsam genutzten Vorlage codieren.
Beachten Sie, dass ich mich absolut aus der Singletons-Are-Evil-Diskussion heraushalte. Das Leben ist zu kurz.
quelle
Ich weiß, dass dies wahrscheinlich zu einem unnötigen Flammenkrieg führen wird, aber ich kann sehen, dass Sie möglicherweise mehr als eine Datenbankverbindung wünschen, daher würde ich zugeben, dass Singleton möglicherweise nicht die beste Lösung dafür ist ... es gibt jedoch solche andere Verwendungen des Singleton-Musters, die ich äußerst nützlich finde.
Hier ein Beispiel: Ich habe mich entschieden, meine eigene MVC- und Template-Engine zu rollen, weil ich etwas wirklich Leichtes wollte. Die Daten, die ich anzeigen möchte, enthalten jedoch viele spezielle mathematische Zeichen wie ≥ und μ und was haben Sie ... Die Daten werden als das eigentliche UTF-8-Zeichen in meiner Datenbank gespeichert und nicht vor HTML codiert, weil Meine App kann neben HTML auch andere Formate wie PDF und CSV liefern. Der geeignete Ort zum Formatieren von HTML befindet sich in der Vorlage ("Ansicht", wenn Sie so wollen), die für das Rendern dieses Seitenabschnitts (Snippet) verantwortlich ist. Ich möchte sie in die entsprechenden HTML-Entitäten konvertieren, aber die Funktion get_html_translation_table () der PHP ist nicht sehr schnell. Es ist sinnvoller, die Daten einmal abzurufen und als Array zu speichern, damit sie allen zur Verfügung stehen. Hier' Als Probe habe ich zusammen geklopft, um die Geschwindigkeit zu testen. Vermutlich würde dies unabhängig davon funktionieren, ob die anderen von Ihnen verwendeten Methoden (nach dem Abrufen der Instanz) statisch waren oder nicht.
Grundsätzlich habe ich typische Ergebnisse wie diese gesehen:
Obwohl ich sicherlich kein Experte bin, sehe ich keinen bequemeren und zuverlässigeren Weg, um den Overhead langsamer Anrufe für irgendeine Art von Daten zu reduzieren und es gleichzeitig super einfach zu machen (einzelne Codezeile, um das zu tun, was Sie brauchen). Zugegeben, mein Beispiel hat nur eine nützliche Methode und ist daher nicht besser als eine global definierte Funktion, aber sobald Sie zwei Methoden haben, werden Sie sie zusammen gruppieren wollen, oder? Bin ich weit weg von der Basis?
Außerdem bevorzuge ich Beispiele, die tatsächlich etwas tun, da es manchmal schwer zu visualisieren ist, wenn ein Beispiel Anweisungen wie "// hier etwas Nützliches tun" enthält, die ich bei der Suche nach Tutorials ständig sehe.
Wie auch immer, ich würde mich über Feedback oder Kommentare freuen, warum die Verwendung eines Singletons für diese Art von Dingen schädlich (oder übermäßig kompliziert) ist.
quelle
Dieser Artikel behandelt das Thema ziemlich ausführlich: http://www.phptherightway.com/pages/Design-Patterns.html#singleton
quelle
Ich habe lange zurückgedacht, hier zu teilen
quelle
Ich stimme der ersten Antwort zu, würde aber auch die Klasse als endgültig deklarieren, damit sie nicht erweitert werden kann, da das Erweitern eines Singletons das Singleton-Muster verletzt. Außerdem sollte die Instanzvariable privat sein, damit nicht direkt auf sie zugegriffen werden kann. Machen Sie die __clone-Methode auch privat, damit Sie das Singleton-Objekt nicht klonen können.
Unten finden Sie einen Beispielcode.
Beispiel Verwendung
Was dies Sie davon abhält (was das Singleton-Muster verletzen würde ..
DU KANNST DAS NICHT MACHEN!
quelle
Dies sollte der richtige Weg von Singleton sein.
quelle
Ich mochte die @ jose-segura-Methode zur Verwendung von Merkmalen, mochte aber nicht die Notwendigkeit, eine statische Variable für Unterklassen zu definieren. Im Folgenden finden Sie eine Lösung, die dies vermeidet, indem die Instanzen in einer statischen lokalen Variablen an die Factory-Methode zwischengespeichert werden, die durch den Klassennamen indiziert ist:
Die Verwendung ist die gleiche wie bei @ jose-segura, nur dass die statische Variable in Unterklassen nicht benötigt wird.
quelle
Eine Datenbankklasse, die prüft, ob eine Datenbankinstanz vorhanden ist, gibt die vorherige Instanz zurück.
Siehe http://www.phptechi.com/php-singleton-design-patterns-example.html
quelle
Dies ist das Beispiel für das Erstellen eines Singletons für die Datenbankklasse
Entwurfsmuster 1) Singleton
dann wird ausgegeben -
Verwenden Sie nur eine einzelne Instanz und erstellen Sie keine 3 Instanzen
quelle
Kurzes Beispiel:
Hoffe Hilfe.
quelle
Hier ist mein Beispiel, das die Möglichkeit bietet, als $ var = new Singleton () aufzurufen und außerdem 3 Variablen zu erstellen, um zu testen, ob ein neues Objekt erstellt wird:
quelle