Singleton Pattern für DB Klasse

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Singleton Pattern für DB Klasse

    Hi,

    Ich erweitere gerade meine MySQL Klasse mit dem singleton pattern. Dafür habe ich das untere in die DB Klasse eingefuegt.

    PHP-Code:
     // Die Singleton Funktion 
        
    public static function singleton() 
        { 
            if (!isset(
    self::$instance)) { 
                
    $c __CLASS__
                
    self::$instance = new $c
            } 

            return 
    self::$instance
        } 
    In meiner index.php hatte ich nun immer diesen part:
    PHP-Code:
     $object=new MySQL ($dbhost,$dbuser,$dbpass,$dbname); 
    Und der constructor hat das dann verwendet:
    PHP-Code:
    public function __construct($dbhost,$dbuser,$dbpassword,$dbname
    wenn ich es richtig verstanden habe faellt dieses nun weg und stattdessen benutze ich dieses
    PHP-Code:
     $object=MySQL::singleton (); 
    Was ich nun jedoch nicht verstehe, wie bekomme ich $dbhost,$dbuser,$dbpass,$dbname an die MySQL Klasse weitergereicht?

    Ich hatte das bereits in einem anderen Forum versucht zu besprechen, dort ging das ganze Thema dann aber in eine Richtung der ich nicht mehr folgen konnte.
    Ich hoffe mir kann hier jemand helfen, da ich einfach nicht weiter komme. Vielen Dank im Voraus.

    Gruss Luka

  • #2
    Re: Singleton Pattern für DB Klasse

    Original geschrieben von Luka

    Was ich nun jedoch nicht verstehe, wie bekomme ich $dbhost,$dbuser,$dbpass,$dbname an die MySQL Klasse weitergereicht?
    Beispielsweise indem du der Singleton-Methode die benötigten Parameter übergibst, die sie ihrerseits an den Konstruktur der Klasse übergibt:
    PHP-Code:

    class Database
    {
        static public function 
    singleton($db_host$db_user, ...)
        {
            if (
    is_null(self::$_instance))
            {
                
    self::$_instance = new self($db_host$db_user, ...);
            }

            return 
    self::$_instance;
        }

        protected function 
    __construct($db_host$db_user, ...)
        {

        }
    }


    $db Database::singleton($db_host$db_user$db_pass$db_name); 
    Du solltest die Sichtbarkeit des Konstrukturs übrigens auf protected einschränken, wenn die Klasse als Singleton implementiert werden soll. Das verhindet nämlich das direkte Erzeugen einer Instanz der Klasse durch new.

    Grüße
    Zuletzt geändert von Griecherus; 26.12.2008, 23:18.
    Nieder mit der Camel Case-Konvention

    Kommentar


    • #3
      Oder eine weitere Methode, die die Instanz initialisiert.
      PHP-Code:
      public static function initInstance($dbhost,$dbuser,$dbpassword,$dbname) {
          
      self::$instance=new self($dbhost,$dbuser,$dbpassword,$dbname);
      }
      public static function 
      getInstance() { 
          if(
      self::$instance===NULL) { 
              throw new 
      Exception('Singleton not initialized');
          }
          return 
      self::$instance

      Das Singleton-Pattern ist aber schon fast ein Anti-Pattern. Meist ist eine Registry anbrachter.

      Kommentar


      • #4
        Oder aber durch eine Setter-Methode:
        PHP-Code:
        public function __set($name$value)
        {
            switch (
        $name)
            {
                case 
        'db_host';
                    
        $this->db_host = (string)$value;
                    break;

                ...
            }
        }

        $db Database::singleton();

        $db->host 'localhost';
        $db->user 'me';
        $db->pass 'secret';
        ...

        $db->connect(); 
        Wenngleich ich keine Motivation sehe, das strukturell so zu lösen, ist es technisch eine Möglichkeit. Was das Registry-Pattern angeht, schließe ich mich PHP-Desaster an.
        Nieder mit der Camel Case-Konvention

        Kommentar


        • #5
          Ich möchte meine DB Verbindung ja in einer anderen Klasse nutzen. Daher hatte ich bisher das $object an meine Login Klasse übergeben.

          Ich verstehe nun jedoch nicht wie ich es mit dem singleton mache
          PHP-Code:
          object=MySQL::singleton (); 
          gehört das in die index.php und ich muss weiter das $object an die Login Klasse übergeben oder gehört der Part in die die Login Klasse selber und es wird nichts mehr übergeben?

          Kommentar


          • #6
            Original geschrieben von Luka
            Ich möchte meine DB Verbindung ja in einer anderen Klasse nutzen. Daher hatte ich bisher das $object an meine Login Klasse übergeben.
            Und wieso sollte das jetzt nicht mehr gehen?
            PHP-Code:
            $db Database::singleton(
                
            $db_host,
                
            $db_user,
                
            $db_pass,
                
            $db_name
            );

            $login = new Login($db);

            // login.class.php
            class Login
            {
                protected 
            $_db null;

                public function 
            __construct(Database $db)
                {
                    
            $this->_db $db;
                }

            Wenn du das Singleton-Entwurfsmuster allerdings zweckentfremden und daraus einen "Globalisator" für deine Klassen machen möchtest, sieht das Ganze wieder anders aus:
            PHP-Code:
            class Login
            {
                protected 
            $_db null;

                public function 
            __construct()
                {
                    
            // hier musst du nun natürlich dafür sorgen, dass die benötigten
                    // Parameter existieren, also sie entweder dem Konstruktor
                    // der Klasse ´Login` übergeben (was sehr unsauber gelöst
                    // wäre) oder sie irgendwie* aus einem/dem global Skopus
                    // holen
                    
            $this->_db Database::singleton($db_host, ...);
                }

            Ich sage dabei aber nicht ohne Grund "zweckentfremden", denn dafür ist Singleton nicht gedacht, sonder das Registry Pattern*, das einen applikationsweiten globalen Gültigkeitsbereich (Skopus) für Parameter, Instanzen, Ressourcen usw. bereit stellt.
            Zuletzt geändert von Griecherus; 27.12.2008, 00:59.
            Nieder mit der Camel Case-Konvention

            Kommentar


            • #7
              Hi,

              ok, ich glaube ich habe das mit dem Singleton völlig falsch verstanden. Ich dachte mir das eigentlich so, ich instanziere einmal das Objekt der MySQL Klasse. Das wird dann dank singleton wie soll man sagen, abgespeichert ist vielleicht das falsche Wort, aber mir fällt nichts besseres ein. Danach muss ich dann das Objekt nicht mehr an meine anderen Klassen übergeben sondern kann einfach über singleton in jeder beliebigen Klasse darauf zugreifen.

              Wenn ich mir das jetzt so anschaue, ist das aber wohl nicht der Fall. Gibt es denn ein Pattern, was genau das macht was ich beschreibe? Benutzt Ihr singleton für Eure DB Verbindung oder was macht Ihr?

              Kommentar


              • #8
                Benutzt Ihr singleton für Eure DB Verbindung oder was macht Ihr?
                Definitiv NEIN!
                Ich arbeite meist mit einer Kombination aus Factory + Registry in meinem Application Object. Fertig!

                Optimaler wäre das "Dependency Injection Design Pattern". Aber das ist meist mit Kanonen auf Spatzen in einer normalen PHP Anwendung.
                Wir werden alle sterben

                Kommentar


                • #9
                  Wenn ich mir das jetzt so anschaue, ist das aber wohl nicht der Fall. Gibt es denn ein Pattern, was genau das macht was ich beschreibe? Benutzt Ihr singleton für Eure DB Verbindung oder was macht Ihr?
                  Wieso nicht? Bei dir ist nunmal der Fall, dass dieses einzelne Objekt noch Parameter von außen benötigt, d.h. du musst die Instanz erst korrekt initialisieren.
                  Den Rest hat combie ja bereits sehr gut beantwortet.

                  Kommentar

                  Lädt...
                  X