2009-12-08 2 views
5

J'ai un ensemble de méthodes de classe statique. J'ai également une connexion de base de données existante dans un script stocké dans une variable d'objet $ DB. Comment puis-je appeler ces méthodes de classe statique et les laisser utiliser cet objet $ DB sans avoir à leur passer cette variable à chaque fois comme un paramètre sur la méthode de classe?PHP: Comment passer une connexion de base de données existante à des méthodes de classe statiques?

Par exemple, en ce moment, je vais avoir à utiliser un malheureusement global,:

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

Il est comme je l'ai besoin de ma classe statique pour appeler lui-même avec une routine qui obtient en quelque sorte la connexion DB $ sans avoir à le rétablir. Remarque: je ne peux pas l'injecter dans la classe statique car elle n'est pas instanciée.

Bien sûr, le problème est résolu si je passe d'une classe statique à une classe normale et instancie mon objet $ Foo. Je pourrais alors injecter le $ DB var comme paramètre sur une variable publique. Ou ajoutez une méthode publique pour recevoir la variable $ DB, puis définissez une variable privée de l'objet $ Foo. Ou, faites en sorte qu'un constructeur de classe accepte la variable $ DB et définisse une variable privée de l'objet $ Foo. Mais toutes les 3 techniques exigent que je passe d'une classe statique à une classe régulière.

Certaines personnes ont mentionné quelque chose appelé un motif de registre ou un motif Singleton (je pense que c'est la même chose? Pas sûr). Est-ce ce dont j'ai besoin pour résoudre ce problème efficacement? La chose la plus importante est que j'évite d'appeler "global $ DB" parce que les gens paniquent à ce sujet.

Répondre

10

Je voudrais et j'utilise le modèle singleton pour cela. J'utilise une classe que je vais appeler Database_Manager ici:

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; 
    } 
} 

Vous pouvez régler les choses une fois avec le initializeConnection() appel, puis il suffit d'appeler Database_Manager :: GetDB() à partir de là dehors. La bonne chose à propos de cette approche est qu'elle est facilement modifiée pour gérer les connexions à plusieurs bases de données, et que vous avez la garantie de n'avoir qu'une seule connexion ouverte par base de données.

Notez que j'ai omis certains éléments de l'implémentation de Singleton, comme déclarer la fonction __construct() privée (la plus grande partie de ce qui précède est copiée de la mémoire). Je voulais juste montrer l'approche globale.

+0

C'était exactement ce dont j'avais besoin, et je n'avais pas réalisé qu'une classe statique pouvait maintenir une persistance d'objet à l'intérieur. – Volomike

+0

Bons moments avec Singletons. :) Heureux d'avoir pu aider. – zombat

3

Je pense qu'un Singleton fonctionnerait bien pour ce que vous essayez de faire. Sinon, vous devez utiliser le mot clé "global" qui, comme vous l'avez déjà découvert, est extrêmement coûteux.

+0

Bonne. Je suis sur la bonne voie. Peux-tu me donner un exemple? – Volomike

Questions connexes