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;
}
问题
如果我在同一个页面上有多个查询,results
和 count
变量仍然包含第一个查询的值。想象一下——第一个查询从我的数据库中检索所有用户。假设有 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
}
如果后续查询失败,这将有助于解决您的问题,不会有任何旧的查询数据附加到数据库对象。
情况
我对 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;
}
问题
如果我在同一个页面上有多个查询,results
和 count
变量仍然包含第一个查询的值。想象一下——第一个查询从我的数据库中检索所有用户。假设有 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
}
如果后续查询失败,这将有助于解决您的问题,不会有任何旧的查询数据附加到数据库对象。