【问题标题】:How to execute a large PHP Script?如何执行大型 PHP 脚本?
【发布时间】:2011-02-19 21:47:14
【问题描述】:

嗯,基本上我可能想执行一个脚本,它也可能需要长达 1 小时。

我真正想做的是使用第三方 API 向我的用户发送短信。所以它基本上就像我为我的脚本提供了一组电话号码并触发发送 SMS 的方法。

但是假设发送 1 条短信需要 5 秒,而我想发送 1000 条短信,大约需要 1 到 2 个小时。我无法使用set_time_limit(),因为我在共享主机上。

一种方法是在会话中存储号码并执行每条短信并使用 javascript 刷新该页面直到结束。这样我需要保持浏览器打开,如果我的 Internet 连接断开,执行将停止。

那么,有没有更好的方法呢?

希望我足够清楚地解释我想要什么?我想执行一个大型脚本,该脚本可能需要数小时才能执行而不会超时。

【问题讨论】:

  • 正在从本地计算机与 API 对话,您可以在其中增加时间限制吗?
  • 您可以在共享主机上设置 cron 作业吗?
  • 是的,我确实可以访问 cron 作业

标签: php timeout execution


【解决方案1】:

从命令行或从 shell 脚本、cron 作业等执行的 PHP 脚本没有超时。

对于 CLI 调用的脚本,即使您使用 set_time_limit() 函数动态设置 PHP 脚本的超时时间,它也不起作用。

【讨论】:

【解决方案2】:

从命令行运行的 PHP 脚本不受 max_execution_time 选项的影响。
所以你完全不用担心。

【讨论】:

  • 我如何在共享主机上将它们作为 CLI 运行?我认为我无法访问它。
  • 查看您的控制面板中是否有“cron”部分。这将允许您通过命令行运行 PHP 脚本。
【解决方案3】:

如果您的主机允许,cron 作业是最好的解决方案。 cron 作业基本上是一个普通的 php 脚本,由 Web 服务器以特定的时间间隔自动运行。根据您的需要,我将创建一个每 5 分钟运行一次的脚本,并以 100 个批次处理您的数字(显然您需要调整时间间隔和批次大小以适应)。这将降低您的服务器负载,并防止您因占用资源而与托管服务提供商发生纠纷。

为了跟踪您的脚本应该处理哪个批次,我会设置一个 track_batch 表。这些列应该可以很好地说明如何解决该问题:

id、date_run、start_record、end_record、final_run

基本上:

  • 检查以查看上次的日期 批量运行。如果不是当前日期 (或您选择的任何其他标识符 使用) 用于当前批次,然后 继续。
  • 如果上一次批处理运行是在当前日期,则检查 final_run 列查看是否 你已经完成了处理 所有的数字。
  • 如果您还有数字要处理,请使用开始和结束 结合 MySQL 的记录 限制构建您的数据库查询 脚本将用于获取下一个 批。
  • 处理您的号码。
  • 将此批次的所有信息存储在 track_batch 表中。
  • 如果查询返回的数字数量小于最大值 批量大小,你已经到了尽头 并且可以将 final_run 列设置为 1.

获得脚本后,您需要自行设置 cron 作业。共享主机可能有自己的自定义界面来执行此操作,因此一旦您的脚本正常工作,他们可能是最好的人选。

【讨论】:

    【解决方案4】:

    使用set_time_limit(0) 不是最佳选择,因为这意味着即使您有错误并且您的脚本进入无限循环,它也会无限期运行。

    相反,如果您估计每条短信需要 5 秒,请使用以下方法:

    while( $there_are_more_sms_to_be_sent ){
      set_time_limit(30); // enough spare time, just in case.
    
      // Do your sending, blah blah
    }
    

    这样,时间限制将依次更新为 30 秒。当然,您可能会遇到单个 while 的无限循环问题,但如果您在该 while 内有其他调用,则该限制将阻止 那些 调用受到指责。

    【讨论】:

    • 所以每次循环,计数器是否重置?
    • 没错。我假设您也在使用 cronjob。您应该将它与本技巧一起使用,这样您就可以每次处理 100 条消息,但还要确保您不会用完时间。
    • 您确定可以停止这样的 cron 作业吗?
    • 使用 set_time_limit() 停止进程绝不是一个好主意,因为它可能会在出现不一致的情况下停止。在这种特殊情况下,我假设每条 SMS 需要 5 秒才能发送,因此我建议设置一个 6 倍的上限,以防万一出现问题,例如无限循环或类似情况。
    【解决方案5】:

    您可以还是不能使用set_time_limit()?

    如果可以的话..使用它:

    <?php
    // Runs forever and ever...
    set_time_limit(-1);
    ?>
    

    【讨论】:

    • 呵呵,我不会投反对票,因为它在技术上是正确的,但是如果他是共享主机上的你的邻居,你会建议他允许脚本永远运行吗?! :)
    【解决方案6】:

    使用 JavaScript 的替代方法是将 Refresh 元标记添加到您的页面:

    <meta http-equiv="Refresh" content="2; url=http://yoururl/script.php&step=x" ?>
    

    content="2; url=.. 中的两个告诉浏览器在页面加载后 2 秒加载 url。

    【讨论】:

    • 谢谢,但我已经在我的问题中指定了这一点。我正在寻找服务器端要做的事情。我也知道 CRON,但我认为可能有更多方法
    • 他显然在问如何...... PHP 技术解决方法不是最好的解决方案
    • 我不知道您为什么认为有必要对将近 7 年的帖子做出反应,但要回复:虽然使用 cron 或命令行作业是运行大批量操作的非常好的解决方案,将作业拆分为小步骤并逐步执行它们同样有效。 Cron 很好,你可以在其中使用它,但是当我没有 shell 访问权限时,我成功地在浏览器中运行了 12 多个小时的脚本。
    【解决方案7】:

    如果你可以运行 CRON 作业

    我通常有一个队列、一个经理和一个工人。除非您可以在此模型可以帮助您的时候调用一次 sms api,并且您不必担心超时,因为每个工作人员都会自己管理它。

    我有类似的东西:

    <?php
    // PSEUDO CODE
    // grab pending from queue
    
    // <for> {
    // update to running
    exec("/usr/bin/php /path/to/send.php {$id} > /dev/null &");
    // }
    

    send.php 将发送每条短信。现在我的运行速度为 300/分钟,因为这是您可以在 cron 作业上设置的最大频率

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 2012-02-12
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多