Antworten auf deine Fragen:
Neues Thema erstellen

[PHP OOP] Nutzung eines anderen Objectes in einer Class /Singleton

JPS

Nicht mehr ganz neu hier

Ich habe eine Class Connect, die das Datenbank handling übernimmt bzw übernehmen soll. Diese soll halt überall verfügbar sein auch in anderen Class(en). Ich habe mich entschlossen die als Singleton zu bauen, da ich auch immer nur eine Instanz davon haben will.
Jetzt erstelle ich im Script eine Singleton static Instanz mit $db=Connect::getIinstance();
Code:
static public function getInstance() {
  if (null === self::$instance) { self::$instance = new self; } return self::$instance;
  }

Will ich aber jetzt $db in anderen Klassen nutzen kommen Fehlermeldungen wie (Bezogen auf: $detail=$db->getSelect($sql);):
Undefined variable: db
Call to a member function getSelect() on a non-object

Wo ist der Denkfehler? Auch wenn ich $db vorher im Gesamtkonstrukt als global deklariere, mag er das nicht.
 

tr4ze

Mod | Forum

Teammitglied
PSD Beta Team
Du musst eine Instanz deines DB Objektes an die Aufrufende Klasse übergeben.

Beispiel:
PHP:
class ersteKlasse {
   
  /**
  *
  * @var type Ersteklasse
  * Instanz von Ersteklasse
  */
  protected $instance ;
   
   
  public function __construct($instance) {
   
  $this->instance = $instance ;
   
  return $instance;
  }
}

class zweiteKlasse {
   
  /**
  *
  * @var type Ersteklasse
  * Instanz von Ersteklasse
  */
  protected $ersteKlasse;
   
  /**
  *
  * @var type Instance
  * Instanz von Zweiteklasse
  */
  protected  $instance;
   
  public function __construct($instance,$ersteklasse) {
   
  $this->instance = $instance;
  $this->ersteKlasse = $ersteklasse;
   
  return $instance;
  }
}

$irgendwas = new ersteKlasse('Hallo Ersteklasse') ;

$wasanderes = new zweiteKlasse($irgendwas, 'Hallo zweiteklasse');

var_dump($wasanderes);

Das Beispiel ist natürlich sehr rudimentär(Ich habe auf getter und setter verzichtet), und die OOP Spezialisten werden mich dafür steinigen, zeigt aber hoffentlich das Konzept(dependency injection).

lg
tr4ze
 

JPS

Nicht mehr ganz neu hier

Ich habe das jetzt ein wenig anders gelöst. Ich habe in jeder klasse ne private $db positioniert und im jeweiligen Constructo $this->db= Connect::getInstance(); aufgerufen und hab somit in jeder Klasse $db zur Verfügung. Nach einigen Experimenten mit var_dump $db aus unterschiedlichen Objekten im selben Skript heraus, scheint es auch die selbe Instanz von der Klasse Connect zu sein.
So spare ich mir auf jeden Fall das übergeben des Connect Objektes, da genau das ja auch ohne static und Singleton funktioniert hätte.
 

Duddle

Posting-Frequenz: 14µHz

Ich habe in jeder klasse ne private $db positioniert und im jeweiligen Constructo $this->db= Connect::getInstance(); aufgerufen und hab somit in jeder Klasse $db zur Verfügung
Warum?
Wenn du das Datenbank-Singleton benötigst, dann konstruiere es dir im Code, wo du es benötigst. Dann muss nichts übergeben werden und du kannst die Datenbank auch während der Laufzeit austauschen, ohne dass davon abhängige Klassen darüber informiert werden müssen.


Duddle
 

JPS

Nicht mehr ganz neu hier

Ja darum ging es ja. Die Singleton Methode getInstance() siehst Du ja im Threadstart. Aber das schien ja nicht zu funktionieren. Der Umweg, den ich jetzt nutze, war ja nicht geplant.
 

tr4ze

Mod | Forum

Teammitglied
PSD Beta Team
Warum?
Wenn du das Datenbank-Singleton benötigst, dann konstruiere es dir im Code, wo du es benötigst. Dann muss nichts übergeben werden und du kannst die Datenbank auch während der Laufzeit austauschen, ohne dass davon abhängige Klassen darüber informiert werden müssen.


Duddle
Diesen Einwand verstehe ich nicht, kannst du das etwas genauer beschreiben? :)
 

Duddle

Posting-Frequenz: 14µHz

Diesen Einwand verstehe ich nicht, kannst du das etwas genauer beschreiben?
Situation 1:
Ich habe ein Objekt foo der Klasse A, welches ein lokales Objekt bar von Klasse B hat, wobei B ein Singleton ist. Ich ändere Klasse B irgendwie zur Laufzeit. Objekt foo benutzt die alte Version weiterhin, weil es eine lokale Kopie benutzt. Ich muss Objekt foo darüber informieren, dass sich B verändert hat.

Situation 2:
Ich habe ein Objekt foo der Klasse A, welches ein Objekt bar der Klasse B bei Bedarf konstruiert, wobei B ein Singleton ist. Ich ändere Klasse B irgendwie zur Laufzeit. Objekt foo benutzt beim nächsten Aufruf sofort die neue Klasse, weil es direkt dessen Konstruktor aufruft und somit mit der korrekten Instanz arbeitet.

Situation 1 ist JPS' Ansatz, Situation 2 die meiner Meinung nach bessere.


Duddle
 

tr4ze

Mod | Forum

Teammitglied
PSD Beta Team
Situation 1:
Ich habe ein Objekt foo der Klasse A, welches ein lokales Objekt bar von Klasse B hat, wobei B ein Singleton ist. Ich ändere Klasse B irgendwie zur Laufzeit. Objekt foo benutzt die alte Version weiterhin, weil es eine lokale Kopie benutzt. Ich muss Objekt foo darüber informieren, dass sich B verändert hat.

Situation 2:
Ich habe ein Objekt foo der Klasse A, welches ein Objekt bar der Klasse B bei Bedarf konstruiert, wobei B ein Singleton ist. Ich ändere Klasse B irgendwie zur Laufzeit. Objekt foo benutzt beim nächsten Aufruf sofort die neue Klasse, weil es direkt dessen Konstruktor aufruft und somit mit der korrekten Instanz arbeitet.

Situation 1 ist JPS' Ansatz, Situation 2 die meiner Meinung nach bessere.


Duddle
Aber das Singelton dient doch nur der Kapselung der Instanz, ob ich nun eine statische Methode verwende um den Konstruktor aufzurufen oder den Konstruktor selber aufrufe(was ja streng genommen dann kein singelton mehr ist) sollte doch keinen Unterschied machen?

Oder willst du darauf hinaus für die DB Klasse noch ein Interface zu implementieren welches konkrete DB Klassen ableitet?
 

Duddle

Posting-Frequenz: 14µHz

Ich habe gerade nochmal recherchiert. Offenbar weist PHP Objekte per Referenz zu, nicht per Wert/Kopie (was meine vorige Annahme war). Dann ist JPS' Ansatz soweit korrekt. Die o.g. Probleme würden nur dann auftreten, wenn das Singleton-Objekt entfernt und neu instanziiert wird.


Duddle
 

tr4ze

Mod | Forum

Teammitglied
PSD Beta Team
Ich habe gerade nochmal recherchiert. Offenbar weist PHP Objekte per Referenz zu, nicht per Wert/Kopie (was meine vorige Annahme war). Dann ist JPS' Ansatz soweit korrekt. Die o.g. Probleme würden nur dann auftreten, wenn das Singleton-Objekt entfernt und neu instanziiert wird.


Duddle
Hab ich mir fast gedacht, klassisch aneinander vorbei geredet ;)
Der vollständigkeithalber sollte man vielleicht noch erwähnen das PHP dieses Verhalten ab 5.3+ zeigt... in älteren Versionen muss man selber dafür sorgen das die Instanz eine Referenz ist, was die meisten Frameworks meines Wissens nach auch so machen.
 

JPS

Nicht mehr ganz neu hier

Das Singleton hat ja eigentlich zwei Eigenschaften.
1. Es soll sicherstellen, dass nur eine Instanz der jeweiligen Klasse existiert
2. Eine globalisierte Verfügbarkeit der Instanz.
Wobei Nr. 2 bei PHP ja irgendwie nicht zu trifft, da ja ein explizietes "heranholen" der Instanz nötig ist und eine direkte Nutzung nicht geht.
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Neueste Themen & Antworten

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.565
Beiträge
1.538.066
Mitglieder
67.488
Neuestes Mitglied
Andrew56524
Oben