我有一个很长的脚本要执行,所以当我运行它时,它在我的Web服务器上达到了最大执行时间,最终超时。
为了说明这一点,想象一下我有一个for循环,它进行了一百万次相当密集的操作。我如何将这个循环执行分为几个部分,这样我就不会达到Web服务器的最大执行时间?
非常感谢,
如果你有一个应用程序要循环已知次数(即你确信它会在一段时间内完成),你可以增加循环内的时间限制:
foreach ($data as $row) {
set_time_limit(10);
// do your stuff here
}
这个解决方案将保护您不受一次失控迭代的影响,但会让您的整个脚本在需要时不受干扰地运行。
最佳解决方案是使用http://php.net/manual/en/function.set-time-limit.php以更改超时。否则,您可以使用301重定向在超时时发送到更新的URL。
$threshold = 10000;
$t = microtime();
$i = isset( $_GET['i'] ) ? $_GET['i'] : 0;
for( $i; $i < 10000000; $i++ )
{
if( microtime - $t > $threshold )
{
header('Location: http://www.example.com/?i='.$i);
exit;
}
// Your code
}
浏览器在停止之前只会进行几次重定向,最好使用javascript强制重新加载页面。
有一天,我使用了一种技术,将工作从一个文件拆分为三部分。这只是一个由12万名成员组成的密集行动阵列。我创建了一个拆分器脚本,将数组存储在每个40.000大小的数据库中。然后,我创建了一个HTML文件,重定向到第一个PHP文件,以计算前40.000个元素。在计算了最初的40.000个elment之后,我又有了一个HTML转发到下一个PHP文件,等等
不是很优雅,但它起作用了:-)
如果您在托管服务器上拥有正确的权限,您可以使用php解释器执行php脚本并在后台运行。
请参阅PHP中的异步shell exec。
如果您正在运行一个需要执行未知时间的脚本,您可以使用:
set_time_limit(0);
如果可能的话,您可以制作脚本,以便它处理所需操作的一部分。一旦它完成了10%,你就可以通过AJAX再次调用脚本来执行接下来的10%。但在某些情况下,这不是一个理想的解决方案,这实际上取决于你在做什么。
我用这种方法创建了一个基于网络的爬网程序,例如,它只在我的计算机上运行。如果它必须立即进行操作,它也会超时。因此,它被划分为200个"任务",每个任务在前一个任务完成后通过Ajax调用。工作得很好,自从它开始运行(爬行?)