PHP mysqli 重新连接问题

14

我在使用PHP中的mysqli类时遇到了问题,但是我无法在任何地方找到答案。

在我的脚本中,一个类创建了一个mysqli连接,并在其函数中使用该连接。之后,这个脚本分叉。连接也被子进程使用,但当子进程终止时,父进程遇到连接关闭(MYSQL Server Has Gone Away)的问题。

在切换到mysqli之前(只是使用mysql),我仅仅调用mysql_ping来确保在父进程执行查询之前数据库连接存在。Mysqli有一个类似的ping函数,但如果连接丢失它实际上不会重新连接。我尝试使用mysqli.reconnect=ON全局设置,但没有成功(使用php.ini和ini_set)。

php mysql_connect函数允许您获取一个已存在的连接,因此,如果我使用的是mysql而不是mysqli,则可以在进程分叉之后直接在子进程中重用连接。但是mysqli似乎没有这样的功能...

我唯一能做的就是调用mysqli->ping(),如果返回false,则在父进程中重新连接到数据库。这非常低效,我很想弄清楚如何正确地使用mysqli(无需手动重新连接),而不必改回mysql..

有什么建议吗?

6个回答

19

mysqli_ping() 函数的文档说明如下:如果在您的 php.ini 文件中将全局选项 mysqli.reconnect 设置为 1,则 mysqli_ping() 在检测到连接断开时会重新连接。

更新:自从我在2009年回答此问题以来,PHP大多数情况下已经默认使用mysqlnd 驱动而不是 libmysql。如下面的评论所述,mysqlnd 不支持 mysqli_ping() 函数,并且PHP开发人员有意这样做,根据他们在 https://bugs.php.net/bug.php?id=52561 的“不予修复”答案所述。

因此,在PHP中似乎已经没有自动重新连接的解决方案了。


3
好的,已解决。我之前不知道不能使用ini_set来修改这个变量,所以在php.ini文件中添加了一行代码,但是并不知道文件中已经有了mysli.reconnect=Off这一行。不过,删除那一行并只使用mysqli.reconnect就可以让mysqli->ping()像mysql_ping一样正常工作了。感谢您的帮助! - Evan Carothers
mysqli_ping() 显然不受 mysqlnd 支持,请参见 https://bugs.php.net/bug.php?id=52561 - Damien

0
function IsConnected() {
    if (empty($this->_connectionID) === FALSE && mysqli_ping($this->_connectionID) === TRUE) {
        return true; // still have connect
    }
    $this->_connectionID = false;
    return false; // lose connection
}

0

你可以尝试一些不同的东西... 与其使用 ping,不如尝试发送一个非常简单低强度的查询,比如 "select now()",看看是否能得到更好的结果。


可能有助于解决问题的原因是,MySQL 将您视为活跃用户,而不仅仅是持有连接并占用资源的人。我相信在 my.ini/my.cnf 中有一些超时设置会影响这种行为。如果您可以访问它,也可以查看一下。 - Sabeen Malik

0

你不能使用持久连接吗?另外,真的需要使用fork()吗?


-1

重新安装php会有些过度。在网上找到一个默认的php.ini文件,检查一下你的php.ini文件有多少改变。 - Phalgun

-2

我认为你需要在mysql配置文件my.cnf中设置mysqli.reconnect,而不是php.ini。我无法通过ini_set更改重新连接,但我的系统管理员在my.cnf中完成了此操作。

所以,有些困惑其他人是如何在php.ini中完成的....


1
不是真的。my.cnf 只与 MySQL 服务器相关,因此通常不会对 PHP 客户端产生影响,而 mysqli 只存在于 PHP 中。mysqli.reconnect 是一个 PHP 配置设置。 - Synchro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接