PHP:循环非常长的函数没有响应时退出并显示警报

时间:2010-07-14 11:48:30

标签: php mysql timeout

我有这个大功能(1300多行代码),它从Web获取数据并将其插入本地数据库。每次运行该函数需要花费20秒才能完成,我需要运行这个函数一百万次,所以我使用set_time_limit(0)将PHP时间限制设置为无限,并将函数循环一百万次,如这个:

for ($ID= '01'; $ID < '999999'; $ID++) {
    getDataFromWeb($conn, $ID);
}

那么问题是什么?问题是,有一百万件事情可能会出错并且总是出错了,例如,代码突然停留在ID 23465中,它只是停止获取数据,但我没有遇到任何错误,就像循环继续但没有向数据库插入任何东西,并且由于'没有时间限制'我设置为PHP然后它永远不会停止。

我想知道如何检测这类问题,停止所有并显示警报。如果我在函数开始之前设置了时间,然后在函数结束时检查它,如下所示:

for ($ID= '01'; $ID < '999999'; $ID++) {
    $time_start = microtime();
    getDataFromWeb($conn, $ID);
    $time_end = microtime();
    if ($time_alert - //... somehow check how time does it takes and stop if its taking too much
}

它不起作用,因为如果函数永远不会完成,那么$ time_end将永远不会被设置等等......

那么,请帮忙吗?

5 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

如果getDataFromWeb($conn, $ID);使用像 libcurl 等类似的库,那么在那里设置连接时间限制可能是个好主意吗? 或者仅调试echo '.'以了解该功能已完成并退出。

答案 2 :(得分:0)

好的 - 这里有几件事情是我心中的红旗。

首先 - 当你说你循环这一百万次时,你不是在开玩笑。这让我感到惊讶。

第二 - 这个循环对我来说很奇怪:

for ($ID= '01'; $ID < '999999'; $ID++)

为什么不这样做:

for ($ID = 1; $ID < 999999; $ID++)

我不明白你为什么要使用字符串进行整数计数。

第三 - 你是如何执行这个的?是来自浏览器还是来自CLI

最后 - 在没有看到代码的情况下很难说出发生了什么,但该函数在完成时是返回真/假布尔值,还是在打印调试的函数中它们的其他触发器(如echo语句(至少))信息,以便您可以跟踪进度。

您可能希望简化getDataFromWeb函数中的代码,它听起来像运行某种cURL请求,解析该数据并将其放入“$ conn”数据库中。如果你将特定任务从该函数分成单独的函数(或者创建一个类),可能更容易理解,但是读取一个用于获取数据,一个用于“清理”数据,一个用于将数据输入数据库。如果一个函数有太多的任务,那么像这样的问题(调试)将成为一场噩梦。

答案 3 :(得分:0)

你的getDataFromWeb()函数中有没有mysql_error()/ mysql_errno()函数?如

if(mysql_errno($conn))
{ 
  echo mysql_errno($conn) . ": " . mysql_error($conn);
}

来自http://php.net/manual/en/function.mysql-error.php

要停止该功能,请用模具替换回声。

答案 4 :(得分:0)

附注:提供的代码不会循环1,000,000次。以下将:

for( $id=1 ; $id<=1000000 ; $id++ ) {
    getDataFromWeb( $conn , $id );
}

此外,关于您需要不断运行此脚本以将内容加载到数据库中,我建议如下:

  • 我假设您正在使用SQL表来保存要抓取的网址,
  • 添加一个名为“loadAttempted”的时间戳字段,
  • 限制PHP脚本尝试执行该操作可能5次,
  • 记录脚本尝试将URL抓取到“loadAttempted”字段
  • 的时间
  • 让脚本的每个循环搜索“loadAttempted”为空或者大于X分钟前的任何网址,
  • 添加CRON作业以触发脚本

这意味着,最多每分钟都会触发脚本并尝试加载5个网址。如果URL需要一段非常长的时间来加载(这意味着脚本在尝试抓取时会超时),它会循环回来并再次尝试。

你也可以使用这个或者这个想法的变体来获取比其余部分慢的页面的统计数据和/或URL的平均加载时间。

另外,如果你想让它不断运行,我建议限制PHP脚本尝试运行getDataFromWeb()函数的次数较少(如5)