2012-12-12 45 views
4

我正在研究CodeIgniter的子查询库(link to project),它通过返回可以使用的数据库对象而不是正常的$this->db对象来工作。克隆CodeIgniter的数据库对象

本来,我是在制造新的数据库每次对象:

$this->CI =& get_instance(); 
$db = $this->CI->load->database('', true); 

但后来我意识到(或者更确切地说,有人向我指出的),这将使每一次新的数据库连接!所以我决定尝试clone而不是制作新的物体。

我更新的代码看起来像这样(link to full code):

class Subquery{ 
    var $CI, $db; 

    function __construct(){ 
     $this->CI =& get_instance(); 
     $this->db = $this->CI->db; // Default database connection 
    } 

    function start_subquery(){ 
     $newDatabase = clone $this->db; 
     // some more code 
     return $newDatabase; 
    } 
} 

我进行了测试,它似乎工作,但我不知道这是否解决了问题。使用clone是否会建立新的数据库连接,还是在内部使用引用并仅保留一个连接?

+1

除非'__clone()'在' - > db'中实现,否则它将使用相同的db连接资源afaik。通过设置和检索某些用户定义的变量(不打算下载CI来测试:P),可以轻松进行测试 – Wrikken

+1

@Wrikken:酷!我看过,它似乎没有'__clone'方法。那很好。我只想要一个连接:-) –

回答

3

首先,=&是不必要的,如果您不使用PHP 4(我假设get_instance返回一个对象)可能有害。

至于clone是否创建一个新的连接..这取决于数据库的实施。据我所知,PDO克隆时不会创建额外的连接。如果你想测试这个,创建一个小脚本,运行start_subquery来达到一定的效果,然后睡眠一段相当长的时间。连接到MySQL并运行:

SHOW STATUS WHERE `variable_name` = 'Threads_connected' 

如果是大于2(您连接到运行查询和脚本中的一个),那么额外的连接正在出于某种原因做。

至于是否你应该克隆数据库,我不知道你为什么想这样做,但我并不真正了解这个类的用例,也不太了解CI。

+1

请注意,在我的生产数据库中,连接的线程很容易进入数百个......如果您只能保证您是当时唯一使用数据库的人, 。对于MySQL,在克隆之前有一个'SET @var ='test';'和克隆之后的'SELECT @var;'更安全(如果是'test',则使用相同的连接)。 – Wrikken

+2

@Wrikken true,我假设他会对自己的mysql实例而不是生产服务器运行它 –

+0

@Wrikken:我可以在我的本地盒子上测试'SHOW STATUS',那里不会有数百个连接: - P = –