0

我最近实现了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);

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

我不知道上面代码的哪一部分生成了脚本超时,并且由于我将它用于时事通讯功能,所以我很难测试或调试它,所以我会非常感谢任何想出的人这个问题的(接近)防弹解决方案:)

提前致谢 !

拉斯

4

4 回答 4

4

如果您可以访问 cron,请用发送时事通讯所需的内容填充数据库,然后使用运行脚本处理少量邮件的 cron 作业弹出队列。

如果你不这样做,请在脚本末尾写一个 system() 语句,让它调用它自己,将下一个时事通讯作为参数传递,然后死掉。因此,您将根据需要发送邮件多次执行脚本。

于 2009-08-17T17:54:01.197 回答
2

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

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

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

于 2009-09-28T07:08:45.293 回答
1

[更新] 下面的数据是我从我的开发框中调用 smtp 服务器的。所以从东欧像样的家庭ADSL 到美国的SMTP 服务器(我的项目Staging 服务器)。当它全部在 Staging 上运行时——所以 localhost php+mysql+Postfix 这个宝贝几乎不需要 1 秒就可以向 30 个收件人发送 5 封单独的电子邮件和密件抄送。颇有见地...

Swiftmaieler 实际上是同步运行的,并等待 SMTP 服务器发送每封电子邮件,以便它获取包含失败邮件地址的数组。因此,如果您将密件抄送给 100 个收件人,总时间为:与服务器通话的时间 + 服务器发送 100 封电子邮件的时间。发送 100 封单独的电子邮件将是 100*(通话时间 + 发送时间)。我的 Postfix 每封电子邮件需要 1 秒,通话时间也是 1 秒,因此发送一封电子邮件需要 2.5 秒。使用标准的 30 秒超时,密件抄送中将有 12 封单独的电子邮件或 20 个收件人。其实都是猜谜游戏:P

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

于 2009-09-28T06:51:20.663 回答
-1

set_time_limit(0);在代码之前

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

于 2009-08-17T17:35:01.703 回答