mysqli::reap_async_query() 有副作用吗?

Does mysqli::reap_async_query() have side effects?

我正在维护一个基于由外部公司编写的遗留代码的项目。我们正在修复此代码库中的许多 PHP 错误,其中一个错误来自对 mysqli::reap_async_query() 的调用:

mysqli::reap_async_query(): Connection not opened, clear or has been closed

这仅在第一次调用此函数时发生:

    function mysqlQuery($sql, $getLastId = false, $die = true, $alwaysDie = false, $async = false)
    {
        @$GLOBALS['con']->reap_async_query(); // This is what is triggering the error
    
        if ($async) {
            $result = $GLOBALS['con']->query($sql, MYSQLI_ASYNC);
        } else {
            $result = $GLOBALS['con']->query($sql);
        }
        if (!$result) {
            if ($alwaysDie or ($_ENV['ENV_MODE'] === 'dev' and $die)) {
                die('Etwas stimmte mit dem Query nicht: ' . $GLOBALS['con']->error . '<br/>Ganzes Query: ' . $sql);
            }
            return false;
        } else {
            $lastId = mysqlLastId();
            if ($getLastId == true) {
                return $lastId;
            } else {
                return $result;
            }
        }
    }

请注意 $GLOBALS['con']mysqli 的一个实例。 代码调用 mysqlQuery() 没有特定参数:

$result = mysqlQuery("SELECT * FROM someTable");

根据 Git 历史记录,添加了对 @$GLOBALS['con']->reap_async_query(); 的调用以支持异步 SQL 查询。但是阅读 PHP 文档,它在这里似乎根本没有用,因为我们没有存储它的 return 值。

所以我的问题是:它出现在这里有什么原因吗,即使不读取它的 return 值就调用它是否有任何重要的副作用? 如果它没用,我可能会完全删除这个调用。

另外,为什么会触发这个错误?我知道在执行任何查询之前尝试读取结果可能会触发错误,但该错误表明连接未激活,但似乎并非如此。

Is there a reason for it [mysqli::reap_async_query()] to be here, does calling it even without reading its return value has any important side effect ?

return 值未分配给局部变量,但它仍然是 returned。

所以最初的兴趣是调用那个函数。以及为了什么,已经写在提交信息中了。

According to the Git history, the call to @$GLOBALS['con']->reap_async_query(); was added to support async SQL queries.

让我们考虑这个例子:

$con->query('SELECT SLEEP(5) as `zzzZZZ...Schnarch...Schmatz..zzz`', MYSQLI_ASYNC);

$con->reap_async_query();

执行这段代码需要多长时间?

这就是该调用支持异步查询的原因。如果异步查询仍然 运行 在连接上(它还没有被收割),每个 新查询都会失败。

因此,到目前为止添加的调用支持异步 SQL 查询,因为它允许在可能用于其他查询的同一(共享)连接上触发一个查询。


另外你问:

Also, why is it triggering this error ? I understand that trying to read a result before any query has been executed could trigger an error but the error indicates that the connection is not active, which does not seem to be the case.

让我们看一下错误,实际上是诊断频道上的一条消息:

PHP Warning: mysqli::reap_async_query(): Connection not opened, clear or has been closed in ...

我们知道连接已经打开,还没有关闭,最后一点可能是:

[...] Connection [...] clear [...]

现在我还没有对该错误消息进行编程,但我读到它是在(打开的)连接上没有异步查询 运行ning - 连接是清晰的。

它会产生一个警告,因为这可能不是有意的(通常不需要获得清晰的连接),此后与您的函数一样,这个 有意的,调用是以错误抑制运算符 (@).

为前缀

感谢@hakre 的回答,我知道这个调用是为了摆脱异步查询队列,我计划用静态标志修复它,以在调用 @$GLOBALS['con']->reap_async_query() 之前检查是否有待处理:

function mysqlQuery($sql, $getLastId = false, $die = true, $alwaysDie = false, $async = false)
{
    static $asyncPending = false;

    if (true === $asyncPending) {
        @$GLOBALS['con']->reap_async_query();
        $asyncPending = false;
    }

    if ($async) {
        $result = $GLOBALS['con']->query($sql, MYSQLI_ASYNC);
        $asyncPending = true;
    } else {
        $result = $GLOBALS['con']->query($sql);
    }
    if (!$result) {
        if ($alwaysDie or ($_ENV['ENV_MODE'] === 'dev' and $die)) {
            die('Etwas stimmte mit dem Query nicht: ' . $GLOBALS['con']->error . '<br/>Ganzes Query: ' . $sql);
        }
        return false;
    } else {
        $lastId = mysqlLastId();
        if ($getLastId == true) {
            return $lastId;
        } else {
            return $result;
        }
    }
}