2013-02-26 52 views
0

传统网站的数据库连接出现意外行为。应用程序连接到同一台服务器上的多个MySQL数据库,并且原始开发人员创建了一个“单例”类,为每个类保存连接对象。持有多个ADODB连接的单身人士

最近,我们已经遇到了一个奇怪的行为与类:在创建extra后创建www的连接,获得的extra实例返回具有当var_dump()看到正确的参数,但实际上是连接到一个连接数据库。

这是什么原因造成的?代码在某个阶段已经工作过。每次调用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不存在”。

+0

你能分享一些让你相信“额外”实际指向'www'的代码吗? – Passerby 2013-02-26 11:31:29

+0

@Passerby:添加了代码示例。 – Kaivosukeltaja 2013-02-26 12:03:33

回答

0

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

2:当你做self::$$dbname->connect(时,if (empty(self::$$dbname))将在下次调用它时返回false。

辛格尔顿在这里描述:http://en.wikipedia.org/wiki/Singleton_pattern

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

+0

如果'empty(self :: $$ dbname)'计算结果为'false','getInstance()'返回先前实例化的连接对象,就像单例所期望的那样。区别在于,不是一个实例,而是四个可能的实例。 – Kaivosukeltaja 2013-02-26 11:59:10