我为我正在开发的项目创建了一个简单的MySQLi类,以便更轻松,更简化地从数据库中提取和推送到数据库。 (也是为了更熟悉PHP中的OOP )
我一直遇到的一个问题是努力使其尽可能高效。我尝试关闭/释放每个查询/语句/结果集。这样做我得到了以下错误:
Warning: mysqli_result::close(): Couldn't fetch mysqli_result
我认为我特意得到了上述内容,因为它试图连续两次关闭查询。
目前我的班级可以做出准备和毫无准备的陈述。所以我尝试在两个地方关闭查询/语句。如果我已经准备好了一个语句,我会在准备语句时进行检查,如果是这样的话,我需要先关闭旧语句,然后才能创建一个新语句,最后在类的析构函数中。
我意识到我可以在拉取并存储结果后关闭查询/语句,但由于某些原因,这似乎很麻烦。一方面,它消除了重复使用准备好的陈述的可能性。同时禁止我在运行后提取有关查询的一些信息,例如受影响的行等。
我知道我可以为每个查询存储此信息,但是只是看起来正确的解决这个问题的方法就是关闭/释放查询/语句,如果我需要再创建一个,那么在剧本的最后。
我试过四处寻找并了解我应该如何正确处理这项任务,但我一直无法想出任何事情。
所以我的问题是,无论如何要测试查询或语句是否需要关闭或释放?或者,我是否有更好的方法来解决这个问题?
感谢任何人提供的任何帮助或见解。
答案 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){}