Einbindung einer Datenbank in andere Klassen

daddz

Mitglied
Hey Leute!

Wie binde ich am geschicktesten und vorallem am "saubersten" eine Datenbankverbindung in eine Klasse ein?

Soll der Klasse eine Instanz der Datenbankverbindungsklasse gegeben werden?
So muss ich ständig die Instanz zwischen den ganzen Klassen "weitergeben" und "umherschieben", was ich nicht besonders schön finde.

Hat da jemand eine elegantere Lösung oder einen Vorschlag?
 
Also wenn Du mehrere Klassen hast die die Datenbankklasse brauchen waere es meiner Meinung nach etwas unguenstig jeweils eine eigene Instanz zu haben. Zum einen duerfte dies Speicher verschwenden und zum anderen eben mehrere Datenbankverbindungen zur Folge haben, was eventuell auch zu lasten der Performance gehen wuerde.

Ob man in Klassen mit global eine globale Variable an Land ziehen kann weiss ich nicht, und es ist auch nicht wirklich schoen.
Eine Moeglichkeit die gehen duerfte waere den Klassen bei der Instanziiehrung eine Referenz auf das Datenbankobjekt zu geben und dann in den Klassen damit zu arbeiten.
Getestet hab ich das noch nicht, sollte meiner Meinung nach aber eigentlich kein Problem sein.

Der Vorteil daran ist dann, dass in den Klassen mit dem Datenbankobjekt arbeiten kann als waere es eine eigene Instanz, aber eben ohne die Nachteile mehrere Instanzen haben zu muessen.
 
Eine Moeglichkeit die gehen duerfte waere den Klassen bei der Instanziiehrung eine Referenz auf das Datenbankobjekt zu geben und dann in den Klassen damit zu arbeiten.
Getestet hab ich das noch nicht, sollte meiner Meinung nach aber eigentlich kein Problem sein.
So habe ich es bis jetzt immer gelöst.
Am Anfang einfach eine Instanz der Datenbankklasse erstellen und den verschiedenen Klassen eine Referenz übergeben. (zumindest in PHP4, denn in PHP5 werden Objekte automatisch als Referenz übergeben)

Dachte da gibt es vielleicht eine etwas schönere Lösung.
Aber dann werde ich wohl dabei bleiben, außer ihr habt noch Vorschläge/Ideen.
 
So, dann mal zum nächsten Problem.

Ich habe eine Klasse Foo :
PHP:
class Foo {
    
    private $_db = null;

    private $_data = null;

    public function __construct($db, $data) {

        $this->_db = $db;
        $this->_data = $data;

    }

    private function _call_bar() {

        $bar = new Bar($this->db, $this->data['foo']);
        $bar->doSomething(); 
        //...usw.
    }

}
Und die Klasse Bar :
PHP:
class Bar {
    
    private $_db = null;

    private $_lessData = null;

    public function __construct($db, $lessData) {

        $this->_db = $db;
        $this->_lessData = $lessData;

    }

}

Nun mal eine Erklärung:

  • Die Klasse Foo bekommt eine Instanz der Datenbankklasse
  • Ebenso bekommt sie ein paar Daten
  • Ein Teil dieser Daten wird mit der Klasse Bar verarbeitet und zurückgegeben
  • Die Klasse Bar braucht aber auch eine Datenbankverbindung

Nun meine Frage:

Ist es "schön", die Instanz von Foo nach Bar "weiterzureichen" (so wie im obigen Beispiel) oder gibt es da bessere Lösungen?

Ich hoffe, ich konnte mein Anliegen gut veranschaulichen! :)
 
Scheinbar hatte bis jetzt keiner von euch eine Idee.

Dafür hatte ich eine! :)

Ich hatte mir gedacht:
Was wenn ich mehrere Klassen so "herumreichen" muss?

Dabei ist mir dann das Registry-Pattern eingefallen.
Im Endeffekt würde es dann so aussehen, dass ich die Klassen die ich brauche in einer Instanz der Registry "registriere" und diese Instanz dann innerhalb meiner Klassen herumreiche.

Wie klingt das?
 
Hi ich hänge gerade an einem ähnlichen Problem bei dem ich mehrere Klassen immer mitschleifen müste. Kannst du des nochmal näher erleutern ... ich werd aus dem Wikieintrag nich so ganz schlau. 0o

MfG
blueX
 
Wie man des am bessten nutzt und anwendet...

Verstehe ich es richtig, dass man alle seine Klassen die man global verwenden kann wie tpl oder db erst instanziert und dann alle diese Instanzen in der Registry zusammen gefasst werden? Dann übergibt man nur immer die Registry und kann über diese dann in den anderen klassen auf die darin enthaltenen Instanzen zugreifen?

MfG
blueX
 
Zuletzt bearbeitet:
Also ich benutze dafür 2 verschiedene Ansätze, der eine ist ebenfalls das Registry-Pattern, die Alternative ist, die Datenbankklasse als Singleton zu implementieren. Das geht natürlich am schönsten in PHP5 ist aber mit einem kleinen Trick auch in PHP4 möglich.

(PHP5):

PHP:
class DB
{
  private static $_instance = null;

  private function __construct()
  {
    // Verbindungsaufbau
  }

  public static function getInstance()
  {
    if(self::$_instance === null)
    {
      self::$_instance = new self();
    }

    return self::$_instance;
  }
}

(PHP4):

PHP:
class DB
{
  function __construct()
  {
    // Verbindungsaufbau
  }

  function & getInstance()
  {
    static $instance = null;

    if($instance === null)
    {
      $instance = new DB();
    }

    return $instance;
  }
}

Dann kannst du überall in jeder Klasse mit
PHP:
$db = DB::getInstance();
deine Instanz der Datenbankklasee benutzen. Finde ich eigentlich so am praktischsten.
 
Zuletzt bearbeitet:
Oh das hatte ich ja ganz außer Acht gelassen! :-(

Der einzige Nachteil bei dieser Lösung ist, dass du in jeder Klasse wissen musst, wie die Datenbankklasse heißt, was bei einer Änderung dieser problematisch werden könnte, da du dann überall den Namen ändern musst.
Außer du benutzt eine eigene Datenbankabstraktion, die immer vor der eigentlichen Datenbankklasse liegt.

Ich habe das Registry-Patter aus dem Wiki-Eintrag mal etwas an meine Ansprüche angepasst und das hier ist dabei herausgekommen:
PHP:
abstract class Registry {

	static private $store = array();
	
	private function __construct() {}
	
	final static public function register($label, $object) {
        
		if(!isset(self::$store[$label])) {
           
			self::$store[$label] = $object;
			
        }
		
    }
	
	final static public function unregister($label) {
	
        if(isset(self::$store[$label])) {
		
            unset(self::$store[$label]);
        
		}
    
	}
	
	final static public function get($label) {
        
		if(isset(self::$store[$label])) {
		
            return self::$store[$label];
			
        }
		
        return false;
		
    }
 
    final static public function has($label) {
	
        if(isset(self::$store[$label]))  {
		
            return true;
			
        }
		
        return false;
		
    }

}
So kann man überall auf die Objekte zugreifen, die darin registriert sind, ohne, dass man jedes mal eine Instanz der Registry "herholen" muss.

Beispiel:
PHP:
Registry::register('database', $dbObj);

// Irgendwo dann:
$dbObj = Registry::get('database');
 
Zurück