【发布时间】:2017-05-26 18:51:27
【问题描述】:
我有一个 PHP 文件,它有时执行时间很长,并且 MySQL 连接(一个 mysqli 对象)过时了。如果我检查与 mysqli_ping 的连接(如果mysqli_ping 返回false,则重新连接),那么我永远不会遇到问题。但是,pinging before every query seems highly inefficient,所以我只想在查询失败时执行 ping 检查(并重新连接)。我的问题是我似乎无法让我的代码在 mysqli_query 失败时引发异常以触发重新连接。
这是我的“基本”代码:
<?php
function query($query) {
$connection = $GLOBALS['global_connection'];
if(empty($connection) || mysqli_connect_errno()) $connection = connect();
try {
$result = mysqli_query($connection, $query);
} catch(Exception $e) {
if(!mysqli_ping($connection)) {
$connection = connect(); // reestablish the connection
$GLOBALS['global_connection'] = $connection; // update global connection value
$result = mysqli_query($connection, $query); // requery using the new connection
}
}
return $result;
}
问题是mysqli_query 中的错误连接不会导致引发异常,但会导致错误出现在我的错误日志中。
我在mysqli_query 之前尝试过mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); (as suggested in other questions),但它不会改变结果。我还在我的 PHP 配置中启用了mysqli.reconnect,但这似乎并没有阻止这一点。
所以我的问题是:
当mysqli_query 失败(由于连接超时)时如何抛出异常?
或
如何高效地自动重新连接数据库?
【问题讨论】:
-
mysqli 函数不会抛出异常,它们只会在失败时返回
FALSE或NULL。你需要用mysqli_errno()检查原因。 -
文档说如果你有
MYSQLND驱动程序,mysqli.reconnect会被忽略。 -
所以我真正需要做的就是:
$result = mysqli_query($connection, $query); if(empty($result)) { if(!mysqli_ping($connection)) { $connection = connect(); // re-establish the connection $GLOBALS['global_connection'] = $connection; // update global connection value $result = mysqli_query($connection, $query); // re-query using the new connection } }...那是我的愚蠢。我在想一个没有结果的搜索会因为某种原因返回 null/false... -
仅供参考,这是错误号 2006。
-
您可以将超时更改为非常短的时间,然后运行一个脚本,该脚本使用
sleep()调用使其断开连接。