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

PHP variables not getting overwritten on subsequent queries

情况

我对 PHP 中的面向对象编程还很陌生,目前我正在创建一个用于学习目的的小型 CMS。我在路上学到了很多关于 OOP 的知识,但我现在面临一个奇怪的问题。我创建了一个 Singleton class 来处理数据库连接和查询。

public static function getInstance()
{
    if(!isset(self::$instance))
    {
        self::$instance = new Database();
    }

    return self::$instance;
}

在同一个class中,也有一个执行查询的方法。它有两个参数,查询和一个带有参数的可选数组,用于为准备好的语句绑定。你可以在下面看到它的来源。

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 个。第二个查询从数据库中检索所有博客文章,假设有 none。如果没有帖子,我想显示一条消息,否则我 运行 循环显示所有结果。在这种情况下,即使没有博客文章也会执行循环,因为 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() 方法只是 return 数据库中的变量 class.

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

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

示例:

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

然后在你的数据库中class:

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

更新:将执行移至响应 class 以进行错误处理

示例用法(未测试)

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

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