在php中制作mysql单例db类的更简单/更好的方法?

时间:2010-01-07 05:38:27

标签: php mysql class singleton

这是我正在使用的那个:

<?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());
    }
}
?>

用法:

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

假设我只希望它连接并执行这个查询功能,那么我应该在课上做出哪些改进?内存或代码效率?

另外,有没有一种有效的方法可以从配置文件中获取数据库凭据?我知道我不能在课堂上使用include。

4 个答案:

答案 0 :(得分:4)

我通常在这种情况下使用延迟初始化,并且只有一个公共方法(在本例中),使用私有构造函数来防止外部实例化(按照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);
  }
}

然后,您可以随时在需要使用时拨打$dbHandle = Database::getInstance()。或者在这种情况下,由于定义了静态查询方法,因此您可以使用Database::query("select * from xx;");而无需调用任何类型的init。

答案 1 :(得分:2)

这很简单,可以正常使用。

您可以将凭据传递给init();

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

答案 2 :(得分:1)

您可以在类

中的函数内使用include
<?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());
    }
}
?>

或者你可以传递变量......

<?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());
    }
}
?>

或者您可以将凭据存储在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());
    }
}
?>

php.ini文件:

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

答案 3 :(得分:1)

对于单身人士类,Dan Breen所遵循的模型是最干净且非常常见的。但是,在这种情况下,我还允许getInstance方法接受一些参数,以便您可以在实例化时覆盖默认配置,或者只是在不创建连接的情况下获取引用(两个用例都是从时间发生的)时间)。

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

..配置/ database.php中:

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

编辑:我已将其更改为更像flyweight,以确保您只为每个连接位置/数据库获取一个实例。这解决了您的顾虑并保持了一定程度的灵活性。