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

问题描述:

我想创建一个简单的使用单例类来连接到mysql数据库和做的查询,代码工作正常,我没有任何问题,但因为我是新来OOP我想知道这是否是不好的做法。php单例数据库连接,这个代码是不好的做法?

这里的类

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); 
+0

Singleton模式通常在数据库类,记录器,前端控制器或请求和响应对象中实现。 – diEcho 2012-02-10 12:05:09

+0

我在这里看不到任何问题 – jere 2012-02-10 12:06:08

+0

你可以看到有大量的db类。甚至可以查看codeigniter等框架以查看其db类的工作方式。 – 2012-02-10 12:06:34

单身人士是坏消息。

  • 它们将全局状态引入程序。大多数程序员应该熟悉为什么全局状态不好。
  • 它们引入了单身人士和任何使用它的类之间的紧密耦合。这意味着你不能重用有问题的类而不重用单例。
  • 他们进行单元测试的类依赖于单身问题,因为你不能轻易地用模拟替换单身。
  • 他们鼓励类尝试解决自己的依赖关系的编码风格。这很糟糕,因为它可能会降低该类的依赖关系的清晰度。
  • PHP有一个Share Nothing架构,这意味着PHP单身人士根本不是单身人士,任何时候都可能有多个实例存在(每个开放请求一个)。
  • 如果您在某个日期后突然发现您确实需要多个由单例提供的资源,会发生什么情况?这是比你想象的更常见的情况

你最好看看,因为它可以解决上述问题。

+0

你能否提供一些关于'dependency-injection'的好文章,以及为什么“Registry for database”是个坏主意? (我知道我可以谷歌它,但确认质量和来自可靠来源的东西) – Vyktor 2012-02-10 12:29:09

+0

注册表在大多数方面(全局状态,鼓励类解决依赖关系等)都像单身人士。至于DI,如果你是谷歌,那么就有很多文章,就像你说的那样。 :)我相信Symfony框架的文档包含了一个很好的关于DI在PHP上下文中的讨论。 – GordonM 2012-02-10 12:34:00

+0

自动装载机类怎么样,(我的答案的扩展名)'get($ connName)'会自动使用'configs/$ connName.ini'初始化连接?我知道你应该提供带有“Controller”连接的“Model”,模型不应该像DBs :: get('export')那样做,但是指定默认连接有什么问题? – Vyktor 2012-02-10 12:39:00

这种模式将被罚款,因为单只适用于当前用户会话。这个决定实际上取决于你的优先权。如果你想为用户提供更快的性能,那么你希望允许每个用户有更多的数据库连接,但是如果你想限制你的数据库被攻击的难度,那么这个单例会给你一个很好的中间路线。

+1

单身汉是个坏消息。他们应该避免。 – GordonM 2012-02-10 12:25:25

+0

@GordonM,非常真实。你的忠告是更审慎的长期解决方案。 – davidethell 2012-02-10 16:32:58

我认为一个单身人士对于连接管理员来说可以,但对于连接本身不是。

你永远不知道什么时候需要为开发的特定部分建立额外的连接。假设您突然需要添加与远程数据库的同步。

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

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

我会说这取决于你使用这个类的方式。如果每次要使用数据库时都致电Database::getInstance(),从面向对象的角度来看,这是不好的,因为它会影响可测试性。如果你只做了一次,然后将实例注入需要使用数据库的对象,那么使用singleton并不坏(但仍然不必要)。

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

我听说在PHP Singleton设计模式的唯一积极的论据是从谁实施的组合,辛格尔顿数据库连接的开发与一个Memcached对象。我实际上没有机会看看代码和性能,但他能够提出一个连贯的论点。我个人并不认为Singleton设计模式与PHP非常相关,无论如何,这在很大程度上都是无状态的(正如在每个请求都会有单例之前所指出的那样)。