我有一个运行PHP脚本的cronjob,它可以获取几百个RSS源,解析它们,更新数据库,然后编写新的Atom和RSS源文件。
当我在浏览器中调用脚本时,脚本运行正常,但是当我让crond运行它时,它会向我发送以下错误:
Warning: mysqli::query(): MySQL server has gone away in /script.php on line 149
以下是脚本中代码的相关部分:
// ...
// the script has now been running for some time,
// fetching feeds, parsing them, and updating the database;
// now we check if the connection to the mysql server is still there,
// and then query the database and write the feed files
if (!isset($mysqli)) {
$mysqli = new mysqli($db_host,
$db_username,
$db_password,
$db_name);
$mysqli->set_charset('utf8');
$mysqli->query("SET lc_time_names = 'de_DE'");
}
$query = "..."; // some SELECT query
if (!($result = $mysqli->query($query))) { // this is line 149
// error message
}
// write the feed files
// ...
如您所见,在发送查询之前,我会检查连接是否存在。显然,数据库服务器会在检查它和执行查询之间断开连接。至少这是我猜的。
那么,为什么会发生这种情况,我该怎么做才能保持连接活着(如果这确实是问题)?
我的PHP脚本在共享服务器上运行(Linux与Apache),并且我没有对MySQL服务器的root访问权限 - 所以没有相关问题可以解决我的问题,因为他们都建议更改设置数据库服务器配置文件。
此外,如果从浏览器调用,则脚本在不同的PHP版本(5.6)下运行,而不是在我执行它时(5.5)。请参阅this related question。
我已按照this answer的建议尝试关闭现有连接并重新建立连接:
$mysqli->close();
if (!isset($mysqli)) {
$mysqli = new mysqli($db_host,
$db_benutzername,
$db_passwort,
$db_name);
$mysqli->set_charset('utf8');
$mysqli->query("SET lc_time_names = 'de_DE'");
}
我试图按照this answer中的建议设置执行时间限制:
set_time_limit(180);
或在拉杰普特王子的回答中:
ignore_user_abort(true);
set_time_limit(0);
但这些都没有帮助。
答案 0 :(得分:0)
第一次尝试解决方案的问题(在我的问题中给出)是关闭连接不会取消设置变量,因此在
中$mysqli->close();
if (!isset($mysqli)) {
if
- 条件始终为假。
一种解决方案是在关闭连接后取消设置变量:
$mysqli->close();
unset($mysqli);
if (!isset($mysqli)) {
但更简单的解决方案是检查连接而不是变量:
if (!mysql_ping($mysqli)) {
(注意,我们当然不会关闭连接以测试它是否打开。)
答案 1 :(得分:0)
在cron作业文件的标题上试试这个:
<?php
ignore_user_abort(true);
set_time_limit(0);
?>