这在 mysqlnd 中不起作用,并被标记为 wontfix:https://bugs.php.net/bug.php?id=52561
(PHP 5, PHP 7, PHP 8)
mysqli::ping -- mysqli_ping — 检测服务器连接,如果连接中断则尝试重新连接
此函数自 PHP 8.4.0 起已弃用。强烈建议不要依赖此函数。
面向对象风格
过程化风格
检查与服务器的连接是否正常。如果连接中断且全局选项mysqli.reconnect已启用,则会尝试自动重新连接。
注意: mysqlnd 驱动程序忽略 php.ini 设置 mysqli.reconnect,因此永远不会尝试自动重新连接。
此函数可用于长时间处于空闲状态的客户端,以检查服务器是否已关闭连接并在必要时重新连接。
如果启用了 mysqli 错误报告 (MYSQLI_REPORT_ERROR
) 并且请求的操作失败,则会生成警告。此外,如果模式设置为 MYSQLI_REPORT_STRICT
,则会抛出 mysqli_sql_exception。
版本 | 描述 |
---|---|
8.4.0 | mysqli::ping() 和 mysqli_ping() 现在均已弃用。reconnect 功能自 PHP 8.2.0 起不再可用,使得此函数已过时。 |
示例 #1 mysqli::ping() 示例
面向对象风格
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* 检查连接 */
if ($mysqli->connect_errno) {
printf("连接失败: %s\n", $mysqli->connect_error);
exit();
}
/* 检查服务器是否存活 */
if ($mysqli->ping()) {
printf ("我们的连接正常!\n");
} else {
printf ("错误: %s\n", $mysqli->error);
}
/* 关闭连接 */
$mysqli->close();
?>
过程化风格
<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* 检查连接 */
if (mysqli_connect_errno()) {
printf("连接失败: %s\n", mysqli_connect_error());
exit();
}
/* 检查服务器是否存活 */
if (mysqli_ping($link)) {
printf ("我们的连接正常!\n");
} else {
printf ("错误: %s\n", mysqli_error($link));
}
/* 关闭连接 */
mysqli_close($link);
?>
以上示例将输出
Our connection is ok!
这在 mysqlnd 中不起作用,并被标记为 wontfix:https://bugs.php.net/bug.php?id=52561
正如 jay at grooveshark dot com 非常有帮助地指出的那样,正在成为标准的 mysqlnd 驱动程序不遵守重新连接命令。如果您有一个数据库包装器类(希望您有),您可以实现您自己的 ping() 版本,例如
<?php
class db extends mysqli
{
private $db_host;
private $db_user;
private $db_pass;
private $db_name;
private $persistent;
public function __construct($db_host, $db_user, $db_pass, $db_name, $persistent = true)
{
$this->db_host = $db_host;
$this->db_user = $db_user;
$this->db_pass = $db_pass;
$this->db_name = $db_name;
$this->persistent = $persistent;
parent::init();
parent::options(MYSQLI_OPT_CONNECT_TIMEOUT, 1);
@parent::real_connect(($this->persistent ? 'p:' : '') . $this->db_host, $this->db_user, $this->db_pass, $this->db_name);
if ($this->connect_errno)
die("所有数据库服务器均已宕机!\n");
}
public function ping()
{
@parent::query('SELECT LAST_INSERT_ID()');
if ($this->errno == 2006)
$this->__construct($this->db_host, $this->db_user, $this->db_pass, $this->db_name, $this->persistent);
}
...
}
$db = new db(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// 某些代码可能需要很长时间才能执行
// 为安全起见,进行 ping 操作以尝试优雅地重新连接
$db->ping();
// 现在我们应该能够再次运行查询了
$db->query('SELECT LAST_INSERT_ID()');
?>
如果需要,您甚至可以将“$this->ping();”放在 db::query() 的顶部,以避免任何显式的重新连接调用,但我并不推荐这样做,因为每次在运行实际目标查询之前运行廉价的“SELECT LAST_INSERT_ID()”查询都会产生(轻微的)开销。可能还有更廉价的查询可以替代“SELECT LAST_INSERT_ID()”,但这是我首先想到的,并且对于大多数用途来说足够廉价,因为您不应该频繁调用 ping()。
在 Debian PHP 包中,选项 mysqli.reconnect 默认设置为关闭。因此,我建议更新关于选项 mysqli.reconnect 建议的第一行描述。(实践笔记;))