2009-12-08 9 views
5

Ho un set di metodi di classe statici. Ho anche una connessione al database esistente in uno script memorizzato in una variabile oggetto $ DB. Come posso chiamare quei metodi di classe statici e lasciare che usino quell'oggetto $ DB senza doverli passare ogni volta come parametro sul metodo di classe?PHP: come passare la connessione del database esistente ai metodi di classe statici?

Per esempio, adesso sto dover utilizzare un globale, purtroppo:

class Foo { 
    public static function Bar() { 
    global $DB; 
    return $DB->DSN_STRING; 
    } 
} 

E 'come ho bisogno della mia classe statica di chiamarsi con una routine che diventa in qualche modo il collegamento $ DB senza dover ristabilirlo. Nota Non posso inserirlo nella classe statica perché non è istanziata.

Naturalmente il problema è risolto se posso passare da una classe statica per una classe normale e creare un'istanza mio oggetto $ Foo. Potrei quindi iniettare la var $ DB come impostazione su una variabile pubblica. Oppure aggiungi un metodo pubblico per ricevere la variabile $ DB e poi imposta una var privata dell'oggetto $ Foo. Oppure, fai in modo che un costruttore di classi accetti la var $ DB e imposti una var privata dell'oggetto $ Foo. Ma tutte e 3 le tecniche richiedono che io passi da una classe statica a una classe regolare.

Alcune persone hanno detto qualcosa chiamato un modello di Registro di sistema o un pattern Singleton (penso che sia la stessa cosa? Non sono sicuro). È questo ciò di cui ho bisogno per risolvere questo problema in modo efficiente?

La cosa più di tutte è che evito di chiamare "$ DB globale" perché la gente fuori di testa per questo.

risposta

10

avrei, e fare, utilizzare il pattern Singleton per questo. Ho utilizzano una classe che mi limiterò a chiamare Database_Manager qui:

class Database_Manager 
{ 
    private static $instance; 
    private $db_connection; 

    public static function getInstance() 
    { 
     if (self::$instance == null) { 
      $className = __CLASS__; 
      self::$instance = new $className(); 
     } 
     return self::$instance; 
    } 

    public static function initializeConnection($connectionInfo) 
    { 
     $db = self::getInstance(); 
     //call init functions.. connect to db, etc 
      //save connection to $db->db_connection; 

    } 

    public static function getDb() 
    { 
     $db = self::getInstance(); 
     return $db->db_connection; 
    } 
} 

È possibile impostare le cose una volta con la chiamata initializeConnection(), e poi basta chiamare Database_Manager :: getDb() da allora in poi.

La cosa bella di questo approccio è che è facilmente modificabile per gestire le connessioni a più database e si ha sempre la possibilità di avere una sola connessione aperta per database.

Si noti che ho omesso parte del nocciolo dell'applicazione di Singleton, ad esempio dichiarando la funzione __construct() privata (la maggior parte di quella sopra è copiata dalla memoria). Volevo solo mostrare l'approccio generale.

+0

Questo era * ESATTAMENTE * ciò di cui avevo bisogno, e non mi ero reso conto che una classe statica potesse mantenere una persistenza dell'oggetto al suo interno. – Volomike

+0

Buoni tempi con Singletons. :) Felice di essere di aiuto. – zombat

3

Penso che un Singleton avrebbe funzionato bene per quello che stai cercando di fare. Altrimenti ti limiti a utilizzare la parola chiave "globale" che, come hai già scoperto, è estremamente costosa.

+0

Buono. Sono sulla strada giusta. Puoi darmi un esempio? – Volomike

Problemi correlati