19

好吧,基本上我可能想要执行一个可能需要长达 1 小时的脚本。

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

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

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

那么,有没有更好的方法来做到这一点?

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

4

7 回答 7

21

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

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

于 2010-05-15T15:56:15.500 回答
6

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

于 2010-05-15T15:55:06.990 回答
5

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

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

id、date_run、start_record、end_record、final_run

本质上:

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

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

于 2010-05-15T16:10:35.747 回答
3

这不是使用的最佳选择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 秒。当然,您可能会遇到该 single 的无限循环问题while,但如果您在该限制内有其他调用,则while该限制将阻止这些调用受到指责。

于 2010-05-15T16:09:33.820 回答
0

可以用还是不能set_time_limit()

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

<?php
// Runs forever and ever...
set_time_limit(-1);
?>
于 2010-05-15T15:55:17.530 回答
0

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

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

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

于 2010-05-15T16:30:56.330 回答
0

如果您可以运行 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 作业上设置的最大频率

于 2010-05-15T16:35:17.673 回答