可以在类之间维护 PDO 连接吗?

Posted

技术标签:

【中文标题】可以在类之间维护 PDO 连接吗?【英文标题】:Can PDO connections be maintained between classes? 【发布时间】:2012-02-20 14:00:32 【问题描述】:

我正在尝试创建一个简单的查询库,并且正在使用 PDO 进行数据库访问。

假设我有以下两个类:

class FirstClass 
    var $dbh;

    function __construct($host,$dbname,$user,$pw) 
        $this->dbh = new PDO ("mysql:host=$host;dbname=$dbname",$user,$pw);
    

    function use_second($foo) 
        return new SecondClass ($foo,$this->dbh);
    


class SecondClass 
    function __construct($foo, $dbh) 
        $sth = $dbh->prepare('SELECT * FROM atable WHERE bar = :foo');
        $sth = $sth->execute(array('foo'=>$foo));
        // do something with the query
    

这是在类之间使用相同 PDO 连接的正确方法吗? - 因为我似乎对此有一些问题,例如,如果我 var_dump 我来自第二类的连接,我得到:

object(PDO)#2 (0)  

这肯定不对吧?

另外,如果我运行一个选择查询,然后转储 $sth 变量,我会得到:

bool(true)

这是因为我处理连接不正确吗? - 如果是这样,我怎样才能在类之间正确使用相同的连接?

【问题讨论】:

从标题中回答问题:是的,他们可以。 当然可以。您可以在询问之前尝试一下,从而节省您和我们的时间。 嗯...我在问题中提到我已经尝试过这个。我说我不相信它工作正常,并想知道我对连接的处理是否导致它 【参考方案1】:

发生这种情况,因为您覆盖了 $sth,这是您的语句,但现在是布尔值:

class SecondClass 
    function __construct($foo, $dbh) 
        // returns PDOStatement:
        $sth = $dbh->prepare('SELECT * FROM atable WHERE bar = :foo');
        // returns boolean:
        $sth = $sth->execute(array('foo'=>$foo));
        // do something with the query
    

要更正它,只是不要覆盖$sth,这样您就可以从中获取结果:

class SecondClass 
    function __construct($foo, $dbh) 
        // returns PDOStatement:
        $sth = $dbh->prepare('SELECT * FROM atable WHERE bar = :foo');
        // returns boolean:
        $success = $sth->execute(array('foo'=>$foo));
        // do something with the query
        if ($success) 
            // do something with $sth->fetchAll() or $sth->fetch(), or anything
            $all_the_results = $sth->fetchAll();
        ;
    

【讨论】:

这个答案是唯一一个实际上解释了这个问题 - 谢谢 @AlexCoplan:谢谢,我很高兴能帮上忙 :)【参考方案2】:

在您的情况下,我会简单地询问(通过询问我的意思是设置先决条件)准备好 PDO 对象。

function __construct($dbh) 
    $this->dbh = $dbh;

通过这种方式,您可以更清楚地了解对象的需求(它不需要用户/密码等,它需要数据库连接!)

它还省去了抽象类(FirstClass),因为你可以直接进入第二类。

【讨论】:

【参考方案3】:

查看PDOStatement::execute 的文档。它返回一个布尔值。 sthtrue 结尾的事实意味着查询成功。

您的设计有点不稳定,因为您正在使用其他对象的非工厂方法创建对象,这可能会造成混淆。理想情况下,您的所有对象都将在控制器执行开始时创建,并注入到需要它们的其他对象中(例如,PDO 对象将在FirstClass::__construct 之外创建,您将拥有类似@987654326 的东西@ 代替。

【讨论】:

以上是关于可以在类之间维护 PDO 连接吗?的主要内容,如果未能解决你的问题,请参考以下文章

PHP开发-PDO

PHP开发-PDO

PHP & PDO - 有啥方法可以建立“安全”的持久连接吗?

在postgresql和PDO之间共享连接(psql)

使用 React-Router 维护 WebSocket 连接

Pypi:我可以声称自己是未维护包的新维护者吗?