php singleton数据库连接,这个代码是不好的做法?

时间:2012-02-10 11:58:54

标签: php mysql oop class singleton

我正在尝试创建一个简单易用的单例类连接到mysql数据库并进行查询,代码工作正常,我没有遇到任何问题,但因为我是OOP的新手我是想知道这是不是坏习惯。

这是班级

class Database {
private $databaseName = 'dbname';
private $host = 'localhost';
private $user = 'user';
private $password = 'pass'; 
private static $instance; //store the single instance of the database

private function __construct(){
    //This will load only once regardless of how many times the class is called
    $connection = mysql_connect($this->host, $this->user, $this->password) or die (mysql_error());
    $db = mysql_select_db($this->databaseName, $connection) or die(mysql_error()); 
    echo 'DB initiated<br>';
}

//this function makes sure there's only 1 instance of the Database class
public static function getInstance(){
    if(!self::$instance){
        self::$instance = new Database();
    }
    return self::$instance;     
}

public function connect() { 
    //db connection
} 
public function query($query) {
    //queries   
    $sql = mysql_query($query) or die(mysql_error()); 
    return $sql;
}

public function numrows($query) {
    //count number of rows  
    $sql = $this->query($query);
    return mysql_num_rows($sql);
}


}

//Intantiate the class
$database = Database::getInstance();

当我想要使用我会做的课时:

$query = "SELECT * FROM registrations";
echo $database->numrows($query);
$sql = $database->query($query);

5 个答案:

答案 0 :(得分:12)

单身人士是坏消息。

  • 他们将全球国家引入计划。大多数程序员应该熟悉全球状态不好的原因。
  • 它们引入了单例与使用它的任何类之间的紧密耦合。这意味着你不能重用有问题的类而不重用单例。
  • 他们对依赖单例问题的类进行单元测试,因为你不能轻易地用mock替换单例。
  • 他们鼓励编写样式,类会尝试解析自己的依赖关系。这很糟糕,因为它可以降低关于类具有哪些依赖关系的清晰度。
  • PHP有一个Share Nothing Architecture,这意味着PHP单例根本不是真正的单例,任何时候都可以存在多个实例(每个打开请求一个)。
  • 如果您稍后突然发现您实际上需要单身人士提供的资源不止一个,会发生什么?这是比你想象的更常见的场景

你最好再看,因为它解决了上述问题。

答案 1 :(得分:2)

我认为单例对于连接管理器来说可以是正常的,但对于连接本身来说则不行。

您永远不知道何时需要为开发的特定部分提供额外的连接。假设您突然需要添加与远程数据库的同步。

连接管理器(可以管理多个连接)可以是单例。连接本身;号

您的连接管理器也应该能够加载“驱动程序”,这样您就可以实现MySQL连接,并且需要msSQL,sqLite或其他任何东西,您就可以添加所需的驱动程序。

答案 2 :(得分:2)

我会说这取决于你使用该类的方式。如果你每次想要使用数据库时都调用Database::getInstance(),那么从OO的角度来看它是不好的,因为它会损害可测试性。如果你只做一次然后将实例注入需要使用数据库的对象,那么使用单例(但仍然没有必要)并不是那么糟糕。

我建议你看看依赖注入概念: http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/http://fabien.potencier.org/article/11/what-is-dependency-injection

答案 3 :(得分:0)

这种模式没问题,因为单例只适用于当前用户会话。这个决定实际上取决于你的优先事项。如果您希望用户获得更快的性能,那么您希望为每个用户提供更多的数据库连接,但如果您想限制数据库的搜索难度,那么单例就可以为您提供良好的中间路径。

答案 4 :(得分:0)

我在PHP中听到的关于Singleton设计模式的唯一正面论据来自于一个与Memcached对象一起实现Singleton数据库连接的开发人员。我实际上没有机会看到代码和性能,但他能够提出一个连贯的论点。

就我个人而言,我并不认为Singleton设计模式与PHP非常相关,而且无论如何都是无状态的(正如在每个请求都有单例之前所指出的那样)。