PHP Datenbankinstanz vererben
kladur
- php
0 ChrisB0 dedlfix0 Sven Rautenberg0 dedlfix
Hallo
ich programmiere ein Forum auf MVC-Basis, und ich möchte gerne, dass man von allen Klassen wie View und Controller auf die Variable, in der die Datenbankinstanz gespeichert ist, zugreifen kann. Ich habs schon versucht dass ich eine Grundklasse mache, die dann die Variable an alle anderen Variablen vererbt, aber das klappt auch nicht. Weiß jemand, wie ich das am besten machen kann?
Für Hilfe wäre ich sehr dankbar.
Mit freundlichen Grüßen
kladur
Hi,
ich programmiere ein Forum auf MVC-Basis, und ich möchte gerne, dass man von allen Klassen wie View und Controller auf die Variable, in der die Datenbankinstanz gespeichert ist, zugreifen kann. Ich habs schon versucht dass ich eine Grundklasse mache, die dann die Variable an alle anderen Variablen vererbt
Das ist keine gute Idee.
Vererbung sollte man bei Objekten anwenden, die Gemeinsamkeiten haben. Deine Datenbank-Klasse hat mit den anderen Klassen eines Forums (Nutzer, Postings, ...) nichts gemein.
Weiß jemand, wie ich das am besten machen kann?
Übergebe die Instanz deiner Datenbankklasse als Parameter.
MfG ChrisB
Hi!
ich programmiere ein Forum auf MVC-Basis, und ich möchte gerne, dass man von allen Klassen wie View und Controller auf die Variable, in der die Datenbankinstanz gespeichert ist, zugreifen kann.
Das ist nicht unbedingt die beste Idee, die sich aber mit dem Singleton-Pattern lösen ließe. Wozu müssen aber View und Controller auf das DBMS zugreifen? Gibt es keine Models, die diese Aufgabe in abstrahierter Form erledigen?
Lo!
Hallo,
danke erstmal für die Antwort. Also ich verwende durchaus Models, und zwar habe ich eine Klasse namens Model die die Grundmodelfunktionen besitzt und automatisch die erbenden Models mit Datenbankanbindung versorgt. Sie wird an alle Models vererbt, und damit vererbt sie auch die Datenbankinstanz an ihre Kindklassen, was ja durchaus erwünscht ist.
Jetzt habe ich aber das Problem, dass ich genau an einer Stelle, nämlich an der, wo bei der Installation die MySQL-Daten getestet werden sollen, die Datenbankverbindung nicht automatisch hergestellt werden soll, sondern ich dies selber mit meiner Funktion $db->conn() machen möchte. Dafür brauche ich eine Instanz $db der Datenbankklasse im Controller.
MfG
Hi!
Also ich verwende durchaus Models, und zwar habe ich eine Klasse namens Model die die Grundmodelfunktionen besitzt und automatisch die erbenden Models mit Datenbankanbindung versorgt. Sie wird an alle Models vererbt, und damit vererbt sie auch die Datenbankinstanz an ihre Kindklassen, was ja durchaus erwünscht ist.
Man muss kein Geschäft erben, um darin einkaufen zu können. Mir scheint, du solltest weiter abstrahieren. So kann man es machen: Die DBMS-Klasse stellt alle datenbankspezifischen Aktionen bereit (RUDI/CRUD), ohne dass irgendwer anderes die konkreten DBMS-Ressourcen zu sehen bekommt. Darauf sitzt eine Schicht, die nicht erbt sondern Funktionen der DBMS-Klasse aufruft, um die Statements abarbeiten zu lassen, die für bestimmte Daten(verarbeitung) notwendig sind. Das kann bereits das Model sein. Je nach Größe des Projekts kann aber auch das Model erst eine weitere Schicht oben drüber sein.
Jetzt habe ich aber das Problem, dass ich genau an einer Stelle, nämlich an der, wo bei der Installation die MySQL-Daten getestet werden sollen, die Datenbankverbindung nicht automatisch hergestellt werden soll, sondern ich dies selber mit meiner Funktion $db->conn() machen möchte. Dafür brauche ich eine Instanz $db der Datenbankklasse im Controller.
Lazy connect. Die DBMS-Klasse fordert erst dann eine geöffnete Verbindung an, wenn sie die wirklich benötigt und nicht auf Vorrat im Konstruktor oder ähnliches. Das heißt, jede Methode, die konkret Querys absetzt, holt sich über ein interenes Singleton die Verbindung. Alle anderen lassen das bleiben, und die Verbindung bleibt nicht vorhanden. Irgendwelche Schichten oben drüber sollen sich nicht um solche "niederen Arbeiten" kümmern müssen/dürfen.
Lo!
Moin!
ich programmiere ein Forum auf MVC-Basis, und ich möchte gerne, dass man von allen Klassen wie View und Controller auf die Variable, in der die Datenbankinstanz gespeichert ist, zugreifen kann. Ich habs schon versucht dass ich eine Grundklasse mache, die dann die Variable an alle anderen Variablen vererbt, aber das klappt auch nicht. Weiß jemand, wie ich das am besten machen kann?
Dein Stichwort lautet "Dependency Injection", und es löst die Fragestellung "Wie kann ein Objekt auf andere Objekte zugreifen, die es zur Erfüllung seiner Aufgabe braucht?"
Für Dependency Injection gibts diverse Ansätze, einfache und komplexe, und sogar ganze Frameworks, in denen man die Abhängigkeiten der Objekte voneinander konfigurieren und fertig benutzbare Instanzen herausbekommt.
Das Singleton-Pattern ist im Übrigen eines, das man nach Möglichkeit vermeiden sollte, insbesondere für Datenbankzugriff.
- Sven Rautenberg
Hi!
Dein Stichwort lautet "Dependency Injection", und es löst die Fragestellung "Wie kann ein Objekt auf andere Objekte zugreifen, die es zur Erfüllung seiner Aufgabe braucht?"
Mit Dependency Injection übergibt man dem empfangenden Object ein anderes Objekt, das es zu seiner Arbeit braucht. Wobei man ihm mal dieses und mal jenes übergeben kann, beispielsweise ein wirklich arbeitendes oder auch mal ein Dummy zum Testen. Sehr nettes Pattern um komplexe Anforderungen flexibel lösen zu können.
Das Singleton-Pattern ist im Übrigen eines, das man nach Möglichkeit vermeiden sollte, insbesondere für Datenbankzugriff.
Ein Singleton eignet sich, wenn ein oder mehrere Objekte wissen, wo sie hingreifen müssen. In dem Fall kann man auch keinen Dummy gezielt unterschieben. Warum aber soll man das vermeiden und warum insbesondere beim Datenbankzugriff?
Lo!
Moin!
Dein Stichwort lautet "Dependency Injection", und es löst die Fragestellung "Wie kann ein Objekt auf andere Objekte zugreifen, die es zur Erfüllung seiner Aufgabe braucht?"
Mit Dependency Injection übergibt man dem empfangenden Object ein anderes Objekt, das es zu seiner Arbeit braucht. Wobei man ihm mal dieses und mal jenes übergeben kann, beispielsweise ein wirklich arbeitendes oder auch mal ein Dummy zum Testen. Sehr nettes Pattern um komplexe Anforderungen flexibel lösen zu können.
Deshalb sehr schlau und definitiv zu bevorzugen. Wobei man sich Frameworks dafür oft schenken kann, sofern man das Zusammenbauen von Klassen schön in eigenen Factory-Klassen kapselt.
Das Singleton-Pattern ist im Übrigen eines, das man nach Möglichkeit vermeiden sollte, insbesondere für Datenbankzugriff.
Ein Singleton eignet sich, wenn ein oder mehrere Objekte wissen, wo sie hingreifen müssen. In dem Fall kann man auch keinen Dummy gezielt unterschieben. Warum aber soll man das vermeiden und warum insbesondere beim Datenbankzugriff?
Singletons sind die Objekt gewordene Reinkarnation der globalen Variablen. Sie sind schwierig vernünftig testbar, sie enthalten sehr leicht "global state", der sich störend auf den Programmablauf auswirken kann, wenn er nicht beabsichtigt ist.
Und die Datenbank ist in den seltensten Fällen zwingend singular. Im Gegenteil: Der Zugriff auf den persistenten Speicher erfolgt immer häufiger so, dass für den jeweiligen Zweck optimierte Speichermethoden benutzt werden, und zwischen den einzelnen Klassen mit "Datenbankzugriff" auch schon mal unterschiedliche. Zumal ein Datenbankzugriff ohnehin Puffer benötigt, die man nicht singletonisieren kann - und mysql_connect() bei zwei Aufrufen mit identischen Parametern die bestehende Connection verwendet, also der Haupteffekt des Singletons schon von der zugrundeliegenden Funktion erfüllt wird.
- Sven Rautenberg
Hi!
Singletons sind die Objekt gewordene Reinkarnation der globalen Variablen.
Wenn man das also haben will, sind sie also ein geeignetes Mittel.
Sie sind schwierig vernünftig testbar, sie enthalten sehr leicht "global state", der sich störend auf den Programmablauf auswirken kann, wenn er nicht beabsichtigt ist.
Wenn man also nicht nach TDD entwickelt ist das kein Nachteil. Inwieweit befürchtest du die negativen Auswirkungen von einem "global state" im konkreten Anwendungsfall?
Und die Datenbank ist in den seltensten Fällen zwingend singular. Im Gegenteil: Der Zugriff auf den persistenten Speicher erfolgt immer häufiger so, dass für den jeweiligen Zweck optimierte Speichermethoden benutzt werden, und zwischen den einzelnen Klassen mit "Datenbankzugriff" auch schon mal unterschiedliche.
Konkretisier das mal bitte. Gern auch an einem Beispiel.
Zumal ein Datenbankzugriff ohnehin Puffer benötigt, die man nicht singletonisieren kann -
In welchem Fall wäre das so? Für den Puffer des Abfrageergebnisses soll ja nicht das Connection-Singleton zuständig sein. Das Resultset hat seine eigene Ressourcenkennung und benötigt ein eigenes Objekt.
und mysql_connect() bei zwei Aufrufen mit identischen Parametern die bestehende Connection verwendet, also der Haupteffekt des Singletons schon von der zugrundeliegenden Funktion erfüllt wird.
Es geht auch darum, die ständig wiederkehrenden Handlungen rund um den Verbindungsaufbau zu zentralisieren. Ob mehrere gleiche mysql_connect() von sich aus die gleiche Connection verwendet ist dabei nicht weiter von wesentlichem Belang.
Lo!