PHP使用循环重新启动脚本执行时间限制

3

我在PHP中运行一个foreach循环,执行时间比我的最大执行时间30秒要长。该循环向用户发送单独的电子邮件。

不是每30秒运行cron作业并为记录创建队列,而是使用set_time_limit(30)在循环中重新启动计数器,这样做是否不道德?

$i = 0; //start count from 0

foreach ($users as $user): 

    //limit emails sent
    if(++$i == 100) break; //ends execution of loop

    set_time_limit(30); //restart timeout counter

    send_email($user); //send email to user

endforeach;

我是新手,但通过上面的代码,我认为我给每封电子邮件30秒的时间来完成发送,但同时当发送100封电子邮件时就会停止循环,以防脚本无限运行。

更新:set_time_limit(0) 违反了托管 TOS 的规定,我相信重新启动超时计数器也将重新启动脚本,而使用CRON也是一样的。


2
不道德?不是。违反主机的服务条款?可能。 - Paul Dessert
你能运行cronjob吗?邮件队列? - ajreal
3个回答

4

在使用foreach循环时,运行set_time_limit可以带来并解决一些问题。

我认为这种解决方案的最大优点是确保没有请求会超过30秒(当你有一个完整的队列时,我相信每个需要超过30秒的脚本都应该被削减)。

它带来的问题是并不一定会执行所有任务。也许你会在作业队列中间遇到问题,导致全部失败。

我会选择这个方案:

# crontab
0,30 * * * * php /path/to/your/script.php

我会用你的脚本。

如果您需要尽可能快地执行作业,我将创建一个bash脚本,该脚本将执行(不带任何超时)php脚本,只要它不以 exit(0) (所有作业都已成功执行)结束,或者不返回 "Done!" 或您喜欢的其他内容。

示例bash脚本:1,2

#!/bin/bash
# Note that false sets $? to 1
false
while [ $? -ne 0 ]; do
    php /path/to/your/script.php >> log.log
done

如果你需要确保没有两个实例同时运行,可以考虑以下方法之一(仅限个人建议):

  • .pid文件
  • mysql中的LOCK TABLE

提示:如果使用上述任何一种方法,请确保脚本在崩溃后仍然能够正常工作。


谢谢你的回答!如果一个邮件发生错误,循环将继续到下一个邮件,我会记录下错误。我会研究你建议的“bash脚本”,虽然我没有经验。 - CyberJunkie
@CyberJunkie,我添加了Bash示例和一些相关资源。 - Vyktor

2

在脚本开始时完全禁用时间限制:

set_time_limit(0);

1
或者设置一个更合理的时间长度。 - Mike Brant
1
我更喜欢他的原始解决方案,它可以解决任何可能出现的挂起邮件服务器的问题。 - Vyktor

0

如果您的主机的服务条款禁止使用无限制脚本,那么他们几乎肯定会反对重置脚本。唯一的选择是并行发送电子邮件,或者转移到另一个主机。


我认为最终我会使用频繁的cron作业。 - CyberJunkie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接