我正在尝试创建一个简单的查询库,而我正在使用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) { }
当然那不对?
此外,如果我运行select查询,然后转储$sth
变量,我只会得到:
bool(true)
这是因为我错误地处理了连接吗? - 如果是这样,我怎样才能在类之间正确使用相同的连接?
答案 0 :(得分:3)
这种情况发生了,因为你覆盖了$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();
};
}
}
答案 1 :(得分:0)
查看PDOStatement::execute的文档。它返回一个布尔值。 sth
在true
结束的事实意味着查询成功。
您的设计有点不稳定,因为您在其他对象的非工厂方法中创建对象,这可能会令人困惑。理想情况下,所有对象都将在控制器执行开始时创建,并注入到需要它们的其他对象中(例如,PDO
对象将在FirstClass::__construct
之外创建,您将拥有比如__construct(PDO $db)
之类的东西。
答案 2 :(得分:0)
在你的情况下,我会简单地询问(通过询问我的意思是设置预先准备)准备好的PDO对象。
function __construct($dbh) {
$this->dbh = $dbh;
}
通过这种方式,您可以更清楚地了解对象需要的内容(它不需要用户/密码等,需要数据库连接!)
它还消除了对抽象类(FirstClass)的需要,因为你可以直接进入第二类。