如何在PHP中执行长任务而不停止其他一切


How to execute a long task in PHP without stopping everything else

我希望能够通过电子邮件从我的服务器发送新闻通讯给我所有的订阅者。数据库中有超过一千个电子邮件地址我需要处理。我刚刚为我创建了一个后台系统,它允许我编写时事通讯并开始发送它们,同时还有一个进度条来监控进度。为了测试而不是发送电子邮件,我调用sleep(1)。然后我意识到,如果我尝试重新加载页面或在脚本运行时运行另一个PHP脚本,什么都不会发生-批量电子邮件进程必须先完成。然后我想起PHP是单线程的,我的系统设计得很糟糕。

我知道有一种方法可以用Thread类来模拟多线程,但是我的主机服务器不支持这个。

另一种明显的方法是将任务分解并使用cron job一点一点地发送一些电子邮件,但这意味着我必须反复验证我的电子邮件服务器,如果我想让我的网站保持活跃,可能在相当短的时间内多达100次。在我的服务器限制下,这可能会抛出一个问题。

显而易见的答案是找一个限制更少的新服务器,或者错开时事通讯以克服任何问题,但这是最后的手段,在这种情况下,我可能会找到一种方法在本地批量发送电子邮件。

是否有任何方法我可以执行一个长时间运行的PHP脚本这样没有延迟每一个其他脚本,直到它完成?

我是否误解了一些相当基本的PHP知识?因为矛盾的是,我发现我可以运行一些长时间运行的脚本(例如,我有一个php脚本,需要大约5秒才能完成,因为它将我的旧数据库转换为新的格式),由于某种原因可以并行运行到其他脚本,它似乎。

是的,我很困惑。请帮助。

编辑:正如wischi正确指出的那样,发送电子邮件的脚本也调用session_start(),因为它需要检查管理员是否登录并出于安全目的调用脚本。

听起来像是在使用会话。

在一个会话中并行运行多个php脚本是不可能的,因为这将导致使用会话变量时的意外行为。

关于此主题的更多信息:

  • http://konrness.com/php5/how-to-prevent-blocking-php-requests/
  • PHP session_start序列化并阻止所有其他共享同一会话

长时间运行的php脚本

在你修复了会话锁定之后,你可能正在寻找一些东西来防止脚本在客户端断开连接(关闭选项卡或取消加载)后被杀死:

如何阻止PHP从发送数据到客户端,而仍然在服务器上运行PHP代码?

你可以试试:

system('php my_mailing_script.php > /tmp/mail_logs.txt &');

不要忘记&符号,它基本上会说:"使用一个新线程来做这件事"。