我有一些PHP-7代码(使用“mysqli”),当然,它想要执行多个查询并滚动它们的结果集。但是,我发现除非我 close()前一个语句,下一个语句......虽然它似乎运行...但没有产生任何结果。
(也就是说,受影响的行数将返回零。)
我无法解释这种行为。 。 。
(顺便说一下,必要的功能似乎是语句 - 关闭。不处理结果集。)
= = =
我不认为这与引用的问题重复,因为答案显然是使用 mysqli_multi_query 而我不是。我在三个连续的循环中执行三个不同的,不相关的查询。
如果你建议我“累积多个结果集”并且只是不知道它,但我不相信这是我的用例。我所见过的那些API调用的唯一引用,特别是使用多个查询调用,我不使用。但我会很高兴来了解我在这里错了。
代码示例
echo "Test: simple query.\n";
$iter = DB::query('select count(*) from address_book');
echo "Query returned " . $iter->rowCount() . " results.\n";
foreach ($iter as $v)
print_r($v);
$iter = null; // WITHOUT this, next stmt will produce no results.
echo "Test: simple query again.\n";
$iter = DB::query('select count(*) from address_book');
echo "Query returned " . $iter->rowCount() . " results.\n";
foreach ($iter as $v)
print_r($v);
$iter = null; // DITTO ...
以下是迭代器支持函数:
// Retrieve current element
public function current () {
if ($this->current == null) {
$this->current = $this->fetch();
}
return $this->current;
}
// Retrieve value of next element
public function next () {
$this->current = $this->fetch();
$this->position++;
return $this->current;
}
// Retrieve key of current element
public function key () {
return $this->position;
}
// Check if current position is valid - used to stop an iterator
public function valid () {
if ($this->position >= 0 && $this->position < $this->rowCount()) {
return true;
}
return false;
}
// Rewind the iterator to the first element
public function rewind () {
$this->checkNoResultException();
$this->position = 0;
$this->_result->data_seek(0);
}
这是'查询':
public static function query ( $stmt, $params = null ) {
$objInstance = self::getInstance();
try {
if ($params === null) {
return $objInstance->query($stmt);
}
else {
return $objInstance->prepare($stmt)->execute($params);
}
}
catch(MysqliException $e) {
error_log("(DB::query) Query failed: " . $e->getMessage());
die("SQL Query failed -- see log");
}
}
答案 0 :(得分:0)
关闭:我结束了“解决”这个问题......有点......通过改变类来对光标做fetch_all()
,存储整个结果 - 设置在一个数组中,然后立即关闭句柄本身。因为我知道我总是在宽大的机器上处理合理大小的结果集,这实际上让我有效地规避了几个......“怪异。”
我从来没有得到令人满意的解释,为什么观察到的行为首先发生。 。
答案 1 :(得分:-1)
我将“回答”这个问题,不是因为它真的得到回答,而是......首先,给RiggsFolly一个“大声喊叫”,立刻跳进去帮助18个评论的交流如上所述。 非常,非常感谢他的敏捷和坚持。
问题尚未完全解决,但我在上面显示的测试用例代码中发现了许多有趣的事情:
•如果您如上所示设置$iter = null;
,则问题可靠地消失...即使将变量设置为null
,不也会使PHP无法执行垃圾收集立即。 (但是,我确实看到了析构函数被立即调用!)
•如果您调用$iter->close()
,我的代码将关闭结果句柄和语句句柄,问题就会消失。
•(!)如果您使用不同的变量来执行第二个查询,问题也就会消失! (换句话说,将$iter
更改为$iter1
和$iter2
。
^^^ 这个最后一个要点非常有趣,意外! ^^^
作为预防措施,我还在statement-object上添加了一个显式__destruct
方法来显式调用它的close()
方法,如果存在,则显式地销毁语句和结果句柄,只要清理确实发生了。这不会影响结果,但我觉得它让我觉得有点温暖和模糊。 。 。
我欢迎任何关于这个问题的进一步见解,因为它肯定会让我感到困惑。 :-D