【问题标题】:Cloning CodeIgniter's database object克隆 CodeIgniter 的数据库对象
【发布时间】:2012-12-12 18:48:30
【问题描述】:

我正在为 CodeIgniter (link to project) 开发一个子查询库,它通过返回您可以使用的数据库对象而不是普通的 $this->db 对象来工作。

最初,我每次都在创建新的数据库对象:

$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 是建立一个新的数据库连接,还是在内部使用引用并且只保留一个连接?

【问题讨论】:

  • 除非在__clone() 中实现->db,否则它将使用相同的数据库连接资源afaik。通过设置和检索一些用户定义的变量来轻松测试(不会下载 CI 来测试:P)
  • @Wrikken:酷!我看过了,似乎没有__clone 方法。那挺好的。我只想要一个连接:-)

标签: php codeigniter


【解决方案1】:

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

至于clone是否创建新连接..这取决于数据库实现。据我所知,PDO 在克隆时不会创建额外的连接。如果您想对此进行测试,请创建一个运行start_subquery 以达到某种效果的小脚本,然后休眠一段相当长的时间。连接mysql并运行:

SHOW STATUS WHERE `variable_name` = 'Threads_connected'

如果超过 2 个(运行查询的连接和来自脚本的连接),则出于某种原因正在建立一个额外的连接。

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

【讨论】:

  • 请注意,在我的生产数据库中,连接的线程很容易进入数百个......只有当你能保证你是当时唯一使用数据库的人时,1 对 2 才有效。对于 MySQL,克隆前的 SET @var = 'test'; 和克隆后的 SELECT @var; 更安全(如果是“测试”,则使用相同的连接)。
  • @Wrikken 是的,我假设他会针对他自己的 mysql 实例而不是在生产服务器上运行它
  • @Wrikken:我可以在本地机器上测试SHOW STATUS,那里不会有数百个连接:-P
  • =& 是因为它在CodeIgniter's docs 中是这样写的(我从来没有真正想过它为什么在那里)。我克隆了数据库,因为这是 CodeIgniter 的active record class 的子查询脚本。没有对子查询的内置支持。克隆是为了在您调用 ->select() 时不会干扰查询的其余部分。
  • 是的,个人测试数据库服务器可以工作(并且应该用于这种事情。但经验告诉我,“生产中的测试”绝非罕见,因此需要快速警告; ) )
猜你喜欢
  • 1970-01-01
  • 2011-11-07
  • 2011-06-23
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 2017-02-11
相关资源
最近更新 更多