【问题标题】:php singleton database connection, is this code bad practice?php单例数据库连接,这个代码是不好的做法吗?
【发布时间】:2012-03-02 21:35:48
【问题描述】:

我正在尝试创建一个简单的使用单例类来连接到 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);

【问题讨论】:

标签: php mysql oop class singleton


【解决方案1】:

这种模式会很好,因为单例只适用于当前用户会话。决定实际上取决于您的优先事项。如果您想为用户提供更快的性能,那么您希望每个用户允许更多的数据库连接,但如果您想限制数据库受到攻击的程度,那么单例可以为您提供一个很好的中间路径。

【讨论】:

  • 单身人士是个坏消息。应该避免它们。
  • @GordonM,非常正确。您的建议是更谨慎的长期解决方案。
【解决方案2】:

我认为单例可以用于连接管理器,但不能用于连接本身。

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

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

您的连接管理器还应该能够加载“驱动程序”,这样您就可以实例化 MySQL 连接,并且在您需要 msSQL、sqlite 或其他任何东西的那一天,您就可以添加所需的驱动程序。

【讨论】:

    【解决方案3】:

    单身人士是个坏消息。

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

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

    【讨论】:

    • 您能否提供一些关于dependency-injection 的好文章以及为什么“数据库注册表”是个坏主意的解释? (我知道我可以用谷歌搜索它,但质量可靠且来源可靠)
    • 注册中心在很多方面都类似于单例(全局状态、鼓励类解决依赖关系等)。至于 DI,如果你用谷歌搜索的话,那里有很多文章,就像你说的那样。 :) 我相信 Symfony 框架的文档包含了在 PHP 上下文中对 DI 的很好的讨论。
    • 自动加载器类怎么样,(我的答案的扩展)get($connName) 将自动初始化与configs/$connName.ini 的连接?我知道您应该为“模型”提供来自“控制器”的连接,并且模型不应该像DBs::get('export') 那样做任何事情,但是指定默认连接有什么问题?
    【解决方案4】:

    我听到的关于 PHP 中的 Singleton 设计模式的唯一积极论点是来自一位开发人员,他结合 Memcached 对象实现了 Singleton 数据库连接。我实际上并没有机会查看代码和性能,但他能够提出一个连贯的论点。

    我个人不认为 Singleton 设计模式与 PHP 非常相关,无论如何它基本上是无状态的(正如在每个请求将有一个单例之前指出的那样)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2012-12-28
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      相关资源
      最近更新 更多