自定义mysqli数据库类返回它不应该的数据

时间:2016-05-20 23:39:50

标签: php mysqli

我正在创建一个MySQLi数据库类供我个人使用,以清理我自己的代码中函数内的预准备语句用法以及我自己的学习和经验。但是,当在一个页面上运行2个或更多查询时,我遇到了一个复杂的问题。

使用我的基本SELECT函数,我可以运行2个查询:

$data = $db->SELECT("SELECT * FROM hist WHERE id = ?", array('i', 2));
$data2 = $db->SELECT("SELECT * FROM hist WHERE id = ?", array('i', 3));

并且如图所示,这两个查询被保存到单独的变量中。

var_dump上执行$data向我显示id=2的正确结果:

array(1) {
  [0]=>
  array(5) {
    ["id"]=>
    int(2)
    ["value"]=>
    float(51.4)
  }
}

然而,在var_dump上执行$data2会向我显示id=2id=3的数据,这些数据表明结果是相互连接的?

array(2) {
  [0]=>
  array(5) {
    ["id"]=>
    int(2)
    ["value"]=>
    float(51.4)
  }
  [1]=>
  array(5) {
    ["id"]=>
    int(3)
    ["value"]=>
    float(476)
  }
}

可能导致这种情况的原因是什么?我是否必须为每个查询启动该类的新实例?我试图在函数结束时取消设置结果数据,但这似乎没有帮助。

我班上的SELECT函数:

public function SELECT($sql, $args=null) {
    if ($stmt = $this->link->prepare($sql)) {
        if(isset($args)) {
            $method = new ReflectionMethod('mysqli_stmt', 'bind_param'); 
            $method->invokeArgs($stmt, $this->refValues($args));
        }
        if(!$stmt->execute()) {
            array_push($this->err, 'execute() failed: ' . htmlspecialchars($stmt->error));
        }           
        $result = $stmt->get_result();

        if (count($result) >= 1) {
            while($row = $result->fetch_array(MYSQLI_ASSOC)) {
                array_push($this->rs, $row);
            }
        } 
        else {
            array_push($this->rs, "No data has been returned.");
        }
    }
    else {
        array_push($this->err, 'prepare() failed: ' . htmlspecialchars($this->link->error));
    }

    if(!empty($this->err)) {
        if($this->debug) {
            return $this->err;
        }
    }
    else {
        return $this->rs;
    }
    $stmt->close();
    unset($this->err);
    unset($this->rs);
}

1 个答案:

答案 0 :(得分:1)

问题在于这部分。

if(!empty($this->err)) {
    if($this->debug) {
        return $this->err;
    }
}
else {
    return $this->rs;
}
$stmt->close();
unset($this->err);
unset($this->rs);

您正在返回$this->rs$this->err,因此unset()永远不会执行,或者更准确地说,正如Arcesilas所说,只有在出现错误并且调试已关闭时才会取消设置变量。

将结果存储在临时变量中并返回结果。

$stmt->close();
if(!empty($this->err)) {
    $result = $this-err;
    unset($this-err);
    if($this->debug) {
        return $result;
    }
}
else {
    $result = $this->rs;
    unset($this->rs);
    return $result;
}

你可以用更干净的代码重构它,但你明白了。

更容易的选择就是移动

unset($this->err);
unset($this->rs);

到函数SELECT的顶部。