PHP如何检查MySQLi查询是否需要关闭?

时间:2009-12-19 06:26:59

标签: php mysql mysqli prepared-statement

我为我正在开发的项目创建了一个简单的MySQLi类,以便更轻松,更简化地从数据库中提取和推送到数据库。 (也是为了更熟悉PHP中的OOP

我一直遇到的一个问题是努力使其尽可能高效。我尝试关闭/释放每个查询/语句/结果集。这样做我得到了以下错误:

Warning: mysqli_result::close(): Couldn't fetch mysqli_result

我认为我特意得到了上述内容,因为它试图连续两次关闭查询。

目前我的班级可以做出准备和毫无准备的陈述。所以我尝试在两个地方关闭查询/语句。如果我已经准备好了一个语句,我会在准备语句时进行检查,如果是这样的话,我需要先关闭旧语句,然后才能创建一个新语句,最后在类的析构函数中。

我意识到我可以在拉取并存储结果后关闭查询/语句,但由于某些原因,这似乎很麻烦。一方面,它消除了重复使用准备好的陈述的可能性。同时禁止我在运行后提取有关查询的一些信息,例如受影响的行等。

我知道我可以为每个查询存储此信息,但是只是看起来正确的解决这个问题的方法就是关闭/释放查询/语句,如果我需要再创建一个,那么在剧本的最后。

我试过四处寻找并了解我应该如何正确处理这项任务,但我一直无法想出任何事情。

所以我的问题是,无论如何要测试查询或语句是否需要关闭或释放?或者,我是否有更好的方法来解决这个问题?

感谢任何人提供的任何帮助或见解。

6 个答案:

答案 0 :(得分:1)

我认为如果结果集中没有剩余行,则应自动关闭。因此,如果遍历整个结果集,则无需调用mysqli_result。但是,如果你只提取包含大约100行的结果集中的第一行,你应该关闭它。

答案 1 :(得分:0)

关闭后可以将其设置为null,并在关闭之前检查析构函数中的null。

显然,当你确定已经完成使用它时,你只想要一个准备好的语句。

答案 2 :(得分:0)

您可以使用RAII或工厂类+引用计数来管理语句。这样你就不需要明确地检查何时关闭任何东西。如果没有看到你如何使用你的包装器的细节,很难详细说明。 Objective-C的访问器模式也可能有用,它看起来像:

private function unsetStatement() {
    if (isset($this->_stmt)) {
        $this->_stmt->close();
        unset($this->_stmt);
    }
}
function getStatement() {
    return $this->_stmt;
}
function setStatement($stmt) {
    $this->unsetStatement();
    $this->_stmt = $stmt;
}

您只能通过上述函数访问语句成员字段,即使在类中也是如此。实际上,它看起来更像是:

-(Statement *)statement {
    return stmt_;
}
-(void)setStatement:(Statement *)stmt {
    [stmt_ release];
    stmt = [stmt retain];
}

答案 3 :(得分:0)

这就是我使用的。如果声明中有任何结果,我知道我需要释放结果:

if($stmt->num_rows() != 0)
{
    $stmt->free_result();

    return FALSE;
}

答案 4 :(得分:0)

如果 mysqli查询结果已经是null,您将在PHP 5中收到以下警告:

 Warning: myfunction(): Property access is not allowed yet in ....

原则上,可以使用自定义错误处理程序处理这些情况,或者只是禁止警告/错误,即is_object($mysqliqresult) && @$mysqliqresult->free()

或者通过statements方法使用mysqli - prepare,而不是直接运行mysqlidblink->查询,如下所示:

$query = "SELECT heptagon,hexagon FROM pentagon ORDER BY hexagon";
$stmt = $dblink->prepare($query);
$stmt->execute();
!$stmt->field_count() && $stmt->free_result();

贾斯汀的建议也很好。

答案 5 :(得分:0)

我找到的最安全的方式:

try { 
    $result->close(); 
} 
catch (Exception $exception){}