PHP变量在后续查询中不会被覆盖

时间:2015-01-13 22:33:02

标签: php mysql pdo

情况

我在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;
}

问题

如果我在同一页面上有多个查询,则resultscount变量仍包含第一个查询的值。想象一下以下内容 - 第一个查询从我的数据库中检索所有用户。让我们说有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类中的变量。

我希望我已经解释了这个问题是可以理解的。回应非常感谢。

1 个答案:

答案 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
}

如果后续查询失败,这将有助于解决您的问题,不会有任何旧的查询数据附加到数据库对象。