我在PHP中面向对象编程相当新,目前我正在为学习目的创建一个小型CMS。我在途中学到了很多关于OOP的知识,但我现在面临着一个奇怪的问题。我已经创建了一个Singleton类来处理数据库连接和查询。
public static function getInstance()
{
if(!isset(self::$instance))
{
self::$instance = new Database();
}
return self::$instance;
}
在同一个类中,还有一种执行查询的方法。它需要两个参数,查询和带有参数的可选数组,用于为预准备语句进行绑定。你可以在下面看到它的来源。
public function execute($query, $params = array())
{
$this->error = false; // Set 'error' to false at the start of each query.
if($this->query = $this->pdo->prepare($query))
{
if(!empty($params))
{
$index = 1;
foreach($params as $parameter)
{
$this->query->bindValue($index, $parameter);
++$index;
}
}
if($this->query->execute())
{
$this->results = $this->query->fetchAll(PDO::FETCH_OBJ);
$this->count = $this->query->rowCount();
}
else
{
$this->error = true;
}
}
return $this;
}
如果我在同一页面上有多个查询,则results
和count
变量仍包含第一个查询的值。想象一下以下内容 - 第一个查询从我的数据库中检索所有用户。让我们说有15个。第二个查询检索数据库中的所有博客帖子,让我们说没有。如果没有帖子,我想显示一条消息,否则我会运行一个循环来显示所有结果。在这种情况下,即使没有博客文章也会执行循环,因为count
变量用于确定数据库中是否有帖子,并且它仍以某种方式保留第一个查询中的15个。
这显然会导致一些错误。与results
相同。它仍保留第一个查询的值。
$query = Database::getInstance()->execute('SELECT * FROM articles ORDER BY article_id DESC');
if(!$query->countRes())
{
echo '<h2>There are no blog posts in the database.</h2>';
}
else
{
foreach($query->results() as $query)
{
echo '<article>
<h3>'.$query->article_heading.'</h3>
<p>'.$query->article_preview.'</p>
</article>';
}
}
countRes()
和results()
方法只返回DB类中的变量。
我希望我已经解释了这个问题是可以理解的。回应非常感谢。
答案 0 :(得分:1)
我会使用响应对象来避免将查询特定数据附加到全局数据库对象。
示例:
<?php
class PDO_Response {
protected $count;
protected $results;
protected $query;
protected $error;
protected $success = true;
public function __construct($query){
$this->query = $query;
try{
$this->query->execute();
}catch(PDOException $e){
$this->error = $e;
$this->success = false;
}
return $this;
}
public function getCount(){
if( is_null( $this->count ) ){
$this->count = $this->query->rowCount();
}
return $this->count;
}
public function getResults(){
if( is_null( $this->results ) ){
$this->results = $this->query->fetchAll(PDO::FETCH_OBJ);
}
return $this->results;
}
public function success(){
return $this->success;
}
public function getError(){
return $this->error;
}
}
然后在您的数据库类中:
public function execute($query, $params = array())
{
if($this -> _query = $this -> _pdo -> prepare($query))
{
if(!empty($params))
{
$index = 1;
foreach($params as $parameter)
{
$this -> _query -> bindValue($index, $parameter);
++$index;
}
}
return new PDO_Response($this->_query);
}
throw new Exception('Some error text here');
}
UPDATE :将执行移至响应类中以进行错误处理
使用示例(未测试)
$select = $database->execute('SELECT * FROM table');
if( $select->success() ){
//query succeeded - do what you want with the response
//SELECT
$results = $select->getResults();
}
$update = $database->execute('UPDATE table SET col = "value"');
if( $update->success() ){
//cool, the update worked
}
如果后续查询失败,这将有助于解决您的问题,不会有任何旧的查询数据附加到数据库对象。