PHP:在服务器强制执行时间限制时编写长时间运行的脚本

时间:2010-05-14 03:12:26

标签: php portability fastcgi execution-time

例如,

FastCGI服务器对PHP脚本施加了执行时间限制,使用PHP中的set_time_limit()无法对其进行更改。 IIS也是这样做的。

我为一个PHP应用程序编写了一个导入脚本,该应用程序在mod_php下运行良好但在FastCGI(mod_fcgid)下失败,因为脚本在一定的秒数后被终止。我还不知道在这种情况下检测你的时间限制的方法,还没有决定我将如何绕过它。使用重定向在小块中执行它看起来像一个kludge,但是如何?

在对长时间运行的任务(例如导入或导出任务)进行编码时,您会使用哪些技术,其中某个PHP脚本可能会在一定的秒数后被服务器终止?

请假设您正在创建一个可移植脚本,因此您不一定知道PHP最终是在mod_php,FastCGI还是IIS下运行,还是在服务器级别强制执行最长执行时间。这可能也排除了shell脚本等。

3 个答案:

答案 0 :(得分:4)

使用不受Web服务器强加的脚本时间限制的PHP command line interface。如果您需要自动执行脚本,可以使用cron安排它。

答案 1 :(得分:-1)

你真正在谈论的是工作排队。这是从前端请求异步运行PHP代码的做法。在PHP中有两种主要的方法。一种是使用名为Gearman的程序,另一种是使用Zend Server Job Queue,我个人比较熟悉。我有一篇关于你如何做到这一点的博客文章Do you Queue。我发现我在那里的实现非常容易使用。

您可能还想尝试在执行逻辑之前将max_execution_time设置为0.

答案 2 :(得分:-1)

  

使用重定向在小块中执行它看起来像一个kludge,但是如何?

当内置导出机制开始达到max_execution_time限制时,这正是我处理完整论坛数据库备份(phpBB)的方式。

我一次只做了一张桌子,而对于5000行的大桌子。 (事实证明,整个过程中的限制因素不是导出时的执行时间,而是phpmyadmin在导入时可以处理的文件大小。)

在每个导出块之后,我返回了一个页面中带有元刷新标记的页面,使用下一个块的表号将脚本重定向回自身,并在查询字符串中开始行。

<?php if(!$all_done){
    $new_url=$_SERVER['PHP_SELF'].'?tablecount='.$count;
    if(!$tabledone && ""!=$start_row && null!=$start_row){
        $new_url.="&startrow=".$start_row;
    } else {
        $new_url.="&startrow=0";
    }
    echo('<meta http-equiv="refresh" content="0.5;url='.$new_url.'" />');
} ?>

计数器是如此,我可以遍历我用SHOW TABLES检索的一组表名。

在我有机智从导出中剔除巨大的单词匹配表(phpBB可以自行重建)之前,这个备份脚本需要半个多小时才能完成。