发送简报时避免PHP超时

时间:2009-08-17 17:33:35

标签: php timeout swiftmailer

我最近实现了Swiftmailer库,但是第一次使用它时,我得到了一个php超时错误,即使它只需要向大约300人发送邮件..(我应该提到使用由于服务器的限制,set_time_limit(0);解决方法不是一个选项。

我使用它的方式是这样的:

 $transport = Swift_SmtpTransport::newInstance('smtp.mydomain.com',25);
 $mailer = Swift_Mailer::newInstance($transport);
 $message = Swift_Message::newInstance();
 $message->setSubject($_POST['subj']);
 $message->setFrom(array('email' => 'Mysite'));
 $message->setTo($recipients);
 $message->setBody(strip_tags($messagebody));
 $message->addPart($messagebody, 'text/html');
 $numSent = $mailer->batchSend($message);
 printf("Sent %d messages\n", $numSent);

其中$recipients是一个逗号分隔的电子邮件数组(使用mySQL查询中的explode()构建)..

我不知道上面代码的哪一部分会产生脚本超时,因为我将它用于新闻稿功能,所以我很难测试或调试它,所以我真的很感谢任何人想出这个问题的(近)防弹解决方案:)

提前致谢!

拉​​斯

4 个答案:

答案 0 :(得分:4)

如果您有权访问cron,请填写数据库以及发送新闻稿所需的内容,然后使用运行脚本处理少量邮件的cron作业弹出队列。

如果不这样做,请在脚本末尾写一个system()语句,使其自我调用,将下一个新闻稿作为参数传递,然后消亡。因此,您将在需要发送邮件的时间内执行脚本。

答案 1 :(得分:2)

限制每封邮件的收件人数量。通过curl或cron调用带有偏移值的脚本“n”次,它不会抛出超时。例如,设置$ limit = 20.然后调用脚本n次:

send.php?offset=0
send.php?offset=20

等等......如果您的根脚本(调用send.php脚本)将超时,那么您可以继续从上一个偏移量发送邮件。

答案 2 :(得分:1)

[更新]以下数据是我从开发框调用smtp服务器的。所以从东欧体面的家庭ADSL到美国的SMTP服务器(我的项目Staging服务器)。当它全部在Staging上运行时 - 所以localhost php + mysql + Postfix这个宝宝只需要1秒就可以发送5个电子邮件和一个BCC给30个收件人。相当一见......

Swiftmaieler实际上是同步行为并等待SMTP服务器发送每封电子邮件,以便它获得邮件地址失败的数组。因此,如果你对100个收件人的BCC总时间是:与服务器通话所花费的时间+服务器发送100封电子邮件的时间。发送100封个人电子邮件将是100 *(通话时间+发送时间)。我的Postfix每封电子邮件需要1秒,通话时间也是1秒,因此发送个人电子邮件需要2.5秒。标准的30秒超时将是BCC中的12个单独的电子邮件或20个收件人。这实际上是一个猜谜游戏:P

所有这些邮件似乎都设计为必须使用set_time_limit(0)。对于有30秒超时的人来说,最聪明的方法是让一个“批量发送”页面保持打开并且有一个ifrme + refresh或Ajax机制,每隔x调用一次“发送邮件包”(一个小的一个10)方法秒。使用Ajax,您可以再次调用脚本响应。

答案 3 :(得分:-1)

代码前的

set_time_limit(0);

编辑:好的,既然您无法使用set_time_limit()函数,为什么不将发送电子邮件的代码放在函数中并使用register_shutdown_function()?这样,当脚本超时时再次调用该函数。