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


PHP variables not getting overwritten on subsequent queries

情况

我对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() 方法只是从数据库类返回变量。

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

我会使用响应对象来避免将查询特定数据附加到全局数据库对象。

例:

<?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');
}

更新:将执行移动到响应类以进行错误处理

示例用法(未测试)

$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
}

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