2010-01-07 9 views
3

est ici celui que je suis en utilisant:Une façon plus simple et plus efficace de créer une classe mysql singleton db en php?

<?php 
final class Database { 
    private static $oDb; 
    public static function init() { 
     if(self::$oDb == NULL) 
     { 
      self::$oDb = mysql_connect('localhost', 'mysql_user', 'mysql_password') or die(mysql_error()); 
      mysql_select_db('mysql_db_name', self::$oDb) or die (mysql_error());; 
     } 
     return self::$oDb; 
    } 
    public function query($sql) 
    { 
     return mysql_query($sql) or die(mysql_error()); 
    } 
} 
?> 

Utilisation:

$oDb = Database::init(); 
$sql = foo; 
$oDb->query($sql); 

En supposant que je ne veux que de se connecter et d'exécuter cette une fonction de requête, y at-il des améliorations que je dois faire sur le classe? Mémoire ou efficacité du code?

De même, existe-t-il un moyen efficace pour obtenir les informations d'identification db à partir d'un fichier de configuration? Je sais que je ne peux pas utiliser inclut dans ma classe.

+0

Pourquoi ne pouvez-vous pas utiliser l'intérieur de votre classe? Il n'y a aucune raison technique pour laquelle vous ne pouvez pas essayer de l'éviter à partir d'une pratique de codage. –

+0

Je pense qu'il pense que vous ne pouvez pas l'utiliser en dehors d'une fonction ... –

+0

Mes fichiers de configuration sont juste des ensembles de 'define (" nom "," valeur ");'. Aucune analyse requise. –

Répondre

4

J'utilise habituellement paresseux pour l'initialisation ce genre de situation et seulement une méthode publique (dans ce cas), avec un constructeur privé pour empêcher l'extérieur instanciation (selon le modèle Singleton):

class Database { 
    private static $instance; 
    private $conn; 

    private function Database() { 
    // do init stuff 
    require_once('dbconfig.php'); // contains define('DB_USER', 'webuser'); etc... 
    $this->conn = mysql_connect(DB_HOST, DB_USER, DB_PASS); // do error checking 
    } 

    public static function getInstance() { 
    if(!self::$instance) { 
     self::$instance = new Database(); 
    } 
    return self::$instance; 
    } 

    public static function query($sql) { 
    $instance = self::getInstance(); 
    return mysql_query($sql, $instance->conn); 
    } 
} 

Ensuite, vous pouvez simplement appeler $dbHandle = Database::getInstance() chaque fois que vous avez besoin de l'utiliser. Ou dans ce cas, puisqu'une méthode de requête statique est définie, vous pouvez utiliser Database::query("select * from xx;"); sans avoir à appeler un type d'init du tout.

+0

Ne pas avoir require_once sur un chemin relatif signifie qu'il serait cassé si j'incluais le fichier de classe lui-même dans un répertoire différent? Comme include 'db.class.php' dans index.php vs admin/index.php – Citizen

+0

En règle générale, je vais définir un ROOT_DIR ou une telle variable en utilisant les fonctions de style dirname() pour obtenir le chemin absolu à la racine de mon site, et puis j'utiliserais quelque chose comme 'require_once (ROOT_DIR. '/ config/db.config.php');'. De cette façon, peu importe où se trouve le répertoire actuel lors de l'acquisition de la configuration. –

+0

Je me demande probablement trop, mais quand j'essaie d'utiliser votre classe, je reçois un trou d'erreur de lapin. Ajout de 'function' à vos lignes 'static public' et ensuite j'obtiens une erreur pour utiliser $ this hors contexte d'objet. Des idées? – Citizen

2

C'est simple comme ça, ça marchera très bien.

Vous pouvez transmettre vos informations d'identification à init();

include(config.php); 
$oDb = Database::init(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD); 
$sql = foo; 
$oDb->query($sql); 
1

Vous pouvez utiliser un include dans une fonction dans une classe

<?php 
final class Database { 
    private static $oDb; 
    public static function init() { 
     if(self::$oDb == NULL) 
     { 
      include('config.php') 
      self::$oDb = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die(mysql_error()); 
      mysql_select_db(DB_NAME, self::$oDb) or die (mysql_error());; 
     } 
     return self::$oDb; 
    } 
    public function query($sql) 
    { 
     return mysql_query($sql) or die(mysql_error()); 
    } 
} 
?> 

ou vous pouvez simplement passer les variables ...

<?php 
final class Database { 
    private static $oDb; 
    public static function init($host, $user, $pass, $name) { 
     if(self::$oDb == NULL) 
     { 
      self::$oDb = mysql_connect($host,$user,$pass) or die(mysql_error()); 
      mysql_select_db($name, self::$oDb) or die (mysql_error());; 
     } 
     return self::$oDb; 
    } 
    public function query($sql) 
    { 
     return mysql_query($sql) or die(mysql_error()); 
    } 
} 
?> 

ou vous pouvez stocker les informations d'identification dans un fichier php.ini

<?php 
final class Database { 
    private static $oDb; 
    public static function init($db_name) { 
     if(self::$oDb == NULL) 
     { 
      self::$oDb = mysql_connect() or die(mysql_error()); 
      mysql_select_db($db_name, self::$oDb) or die (mysql_error());; 
     } 
     return self::$oDb; 
    } 
    public function query($sql) 
    { 
     return mysql_query($sql) or die(mysql_error()); 
    } 
} 
?> 

fichier php.ini:

mysql.default_host="host" 
mysql.default_user="user" 
mysql.default_password="password" 
1

Pour les classes singleton, le modèle Dan Breen suivi est le plus propre et très commun. Cependant, dans ce cas, j'autoriserais également la méthode getInstance à accepter certains paramètres afin que vous puissiez remplacer votre configuration par défaut au moment de l'instanciation, ou simplement obtenir une référence sans créer de connexion (les deux cas d'utilisation arrivent de temps en temps).

database.php

require_once("../path/to/config/database.php"); 

class Database { 
    private static $instances = array(); 

    private function Database($host, $user, $password, $name) { 
    // do init stuff 
    } 

    public static getInstance(
    $host=DB_HOST, $user=DB_USER, $password=DB_PASSWORD, $name=DB_NAME 
) { 
    $key = strtolower($host . $user . $password . $name); 

    if (!$self::instances[$key]) { 
     $self::instances[$key] = new Database($host, $user, $password, $name); 
    } 
    return $self::instances[$key]; 
    } 
} 

..config/database.php:

define("DB_HOST", "localhost"); 
define("DB_USER", "mrsqlguy"); 
define("DB_PASS", "!!!"); 
define("DB_NAME", "just_another_wordpress"); 

Edit: Je l'ai changé pour agir plus comme une masselotte pour vous assurer que vous obtenez seulement une instance pour chaque emplacement/base de données de connexion. Cela répond à vos préoccupations et maintient un certain degré de flexibilité.

+0

Etre flexible, c'est sympa et j'aime bien cette réponse, mais un problème potentiel est que puisqu'il n'est initialisé qu'une seule fois, cela pourrait conduire à des problèmes très étranges plus tard. A savoir, si le programmeur appelle getInstance avec de nouveaux paramètres de connexion, mais ailleurs, il a déjà fait l'appel initial avec des paramètres différents, il peut être difficile de comprendre qu'il n'utilise pas les paramètres passés la deuxième fois. –

Questions connexes