我正在尝试使用ignore_user_abort(true);
和set_time_limit(0);
的脚本在php中创建一个cronjob。基本的工作,但遗憾的是,该过程在15分钟后被服务器终止。
现在我正在使用fopen
通过在被杀之前再次请求页面来绕过这个。这是第一次按预期工作(它截断表,循环然后加载id = 2的页面)。插入id = 2的第二行,循环开始正确。不幸的是,在第2页之后它继续使用相同的Id,它不会继续使用id = 3,4等等。
有人知道如何解决这个问题吗?
我用于测试的示例代码:
<?php
ignore_user_abort(true);
set_time_limit(0);
$interval=1;
$startTime = time();
$maxLoop = 10;
$id = (strlen($_GET['id'])>0) ? trim($_GET['id']) : 1;
require_once('ct2database.php');
ct2database::init();
if ($id==1) {
//init table
ct2database::query("TRUNCATE TABLE crontest");
}
ct2database::query("INSERT INTO crontest (Id, Counter, StartDate) VALUES (".$id.", 0, '".date("Y-m-d H:i:s")."')");
//loop
do{
ct2database::query("UPDATE crontest SET Counter=Counter+1 WHERE id=".$id);
sleep($interval);
}while($maxLoop--);
$newid = $id+1;
$url = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'].'?id='.$newid . '&t='.time();
//regular end of loop
ct2database::query("UPDATE crontest SET EndDateRegular='".date("Y-m-d H:i:s")."' WHERE id=".$id);
$context = stream_context_create( array(
'http'=>array(
'timeout' => 0.5
)
));
$fp = fopen($url, 'r', false, $context);
register_shutdown_function('ShutdownHandler');
function ShutdownHandler() {
global $id;
//update on shutdown
ct2database::query("UPDATE crontest SET EndDateShutdown='".date("Y-m-d H:i:s")."' WHERE id=".$id);
}
set_error_handler("ErrorHandler");
function ErrorHandler() {
global $id;
//update on error
ct2database::query("UPDATE crontest SET EndDateError='".date("Y-m-d H:i:s")."' WHERE id=".$id);
}
?>
结果:
Array
(
[Id] => 1
[Counter] => 10
[DateModified] => 2012-12-21 16:01:54
[StartDate] => 2012-12-21 16:01:42
[EndDateRegular] => 2012-12-21 16:01:53
[EndDateShutdown] => 2012-12-21 16:01:54
[EndDateError] => 0000-00-00 00:00:00
)
Array
(
[Id] => 2
[Counter] => 55
[DateModified] => 2012-12-21 16:02:49
[StartDate] => 2012-12-21 16:01:54
[EndDateRegular] => 2012-12-21 16:02:49
[EndDateShutdown] => 2012-12-21 16:02:49
[EndDateError] => 0000-00-00 00:00:00
)
答案 0 :(得分:1)
我尝试使用这个小例子“重新启动”脚本,到目前为止工作正常。
<?php
if (isset($_GET['id'])) {
$id = $_GET['id'];
} else {
$id = 1;
}
echo "$id ";
++$id;
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'] . '?id=' . $id;
if ($id < 10) {
$fp = fopen($url, 'r');
$buf = fread($fp, 100);
echo $buf;
fclose($fp);
}
但是,我使用PHP_SELF
,因为REQUEST_URI
包含完整路径,包括参数id
。这会建立像http://server/path?id=1?id=2?id=3?id=...
这样的网址。我还读取了脚本的输出,否则当发生某些输出时它可能会阻塞。
要记住的另一点是,这实际上是无休止的递归。这可能会导致connection refused
错误。
因此,真正的解决方案应该是查看服务器日志并找出问题的真正原因。