【问题标题】:Singleton holding multiple ADODB connections持有多个 ADODB 连接的单例
【发布时间】:2013-02-26 11:26:38
【问题描述】:

旧网站的数据库连接出现意外行为。该应用程序连接到同一台服务器上的多个 MySQL 数据库,并且最初的开发人员创建了一个“单例”类来保存每个数据库的连接对象。

最近我们遇到了这个类的一个奇怪行为:在创建extra 之后创建到www 的连接时,获取extra 的实例返回一个连接,当使用@987654324 查看时,该连接具有正确的参数@ 但实际上是连接到www 数据库。

是什么原因造成的?该代码以前在某个阶段工作过。在每次调用 getInstance() 时创建一个新连接可以解决问题,但如果可能的话,我想以正确的方式解决这个问题。

<?php

class DBConnection
{
    private static $default;
    private static $extra;
    private static $intra;
    private static $www;

    public static function getInstance($dbname = "default")
    {
        global $db; // This is an array containing database connection parameters

        if(!($dbname == "default" || $dbname == "extra" || $dbname == "www" || $dbname == "intra"))
        {
            $dbname = "default";
        }

        if (empty(self::$$dbname)) // Making this pass every time fixes the problem
        {
            try
            {
                self::$$dbname = ADONewConnection('mysqlt');
                if(isset($db[$dbname]))
                {
                    self::$$dbname->connect(DBHOSTNAME, $db[$dbname]["dbusername"], $db[$dbname]["dbpassword"], $db[$dbname]["dbname"]);
                }
                else 
                {
                    // fallback
                    self::$$dbname->connect(DBHOSTNAME, DBUSERNAME, DBPASSWORD, DBNAME);
                }

                self::$$dbname->SetFetchMode(ADODB_FETCH_ASSOC);
                self::$$dbname->execute("SET NAMES utf8");

                return self::$$dbname;
            }
            catch(Exception $e)
            {
                exit("DB connection failed");
            }
        }
        else
        {
            return self::$$dbname;
        }
    }
}

这是一个类行为不端的简化示例:

$cn = DBConnection::getInstance("extra");
$cn->debug = true;
$rs = $cn->execute("SELECT * FROM messages WHERE id = ".$this->id);

最后一行失败并显示错误消息“表 www.messages 不存在”。

【问题讨论】:

  • 你能分享一下让你相信extra实际上指向www的代码吗?
  • @Passerby:添加了代码示例。

标签: php mysql singleton adodb


【解决方案1】:

1:不需要在getInstance()中建立连接。 getInstance 不能做任何事情,而是返回 DB 类的实例。

2:当你调用self::$$dbname-&gt;connect( 时,if (empty(self::$$dbname)) 会在你下次调用它时返回 false。

这里描述了单例:http://en.wikipedia.org/wiki/Singleton_pattern

你有什么 - 它只是一个静态方法。

【讨论】:

  • 如果empty(self::$$dbname) 的计算结果为falsegetInstance() 返回先前实例化的连接对象,正如单例所期望的那样。不同之处在于,不是一个实例,而是四个可能的实例。
猜你喜欢
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 1970-01-01
相关资源
最近更新 更多