【问题标题】:Bulk Email with Swiftmailer使用 Swiftmailer 批量发送电子邮件
【发布时间】:2016-04-04 10:08:31
【问题描述】:

我正在使用SwiftMailer 发送批量电子邮件。目前,我用代码来做

$transport = Swift_SmtpTransport::newInstance('*****', 25);
$transport->setUsername('***');
$transport->setPassword('***');

$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance();
$message->setSubject($derBetreff);

$bbc= array('1@web.de','2@web.de','3@web.de',...,'1000@web.de');

$message->setFrom(array('my@email.de' => 'My Name'));           
$message->setTo('my@email.de');
$message->setBcc($bcc);
$message->setBody('Hi this is my email');           
$message->attach(Swift_Attachment::fromPath('myFile.pdf'));     

// Send the message
$result = $mailer->send($message);
echo $result;

我只向自己发送一封电子邮件并在密件抄送中添加约 1000 人。

执行代码并发送一封电子邮件大约需要 9 分钟,它会返回“成功”消息。但是,我的 php.ini 文件中的 max_execution_time 仅设置为 30 秒。

我的第一个问题是:为什么 max_execution_time 没有停止我的 SwiftMailer 脚本?

其次,我找到了AntiFlood Plugin for Swiftmailer,它有助于发送大量电子邮件。下面的脚本通过先发送 100 封电子邮件,然后暂停 30 秒并继续发送接下来的 100 封电子邮件,向每个成员发送一封电子邮件,依此类推。我读过这是避免被标记为垃圾邮件的好习惯。

我的第二个问题是:AntiFlood 插件是否需要非常长的执行时间才能工作?例如,如果我使用下面给出的脚本发送 1000 封电子邮件并且只考虑暂停,那么脚本至少已经运行了 4.5 分钟,对吧?

// Create the Mailer using any Transport
$mailer = Swift_Mailer::newInstance(
  Swift_SmtpTransport::newInstance('smtp.example.org', 25)
);

// Use AntiFlood to re-connect after 100 emails
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100));

// And specify a time in seconds to pause for (30 secs)
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30));

// Continue sending as normal
for ($lotsOfRecipients as $recipient) {
  ...

  $mailer->send( ... );
}

【问题讨论】:

  • 嗨,我需要完成这件事情,你是怎么做到的?
  • @LeeWiggins 您可以安全地使用 Anti-Flood 插件,甚至更好地使用邮件查询。我在这里添加了一个答案:stackoverflow.com/a/47922195/2311074

标签: php swiftmailer bulk-email


【解决方案1】:

首先,电子邮件的发送不会发生在脚本本身中。这就是为什么如果您的服务器在 Linux 上运行,max_execution_time 不会受到影响,请参阅docs

set_time_limit() 函数和配置指令 max_execution_time 只影响脚本的执行时间 本身。在执行之外发生的活动上花费的任何时间 例如使用 system() 的系统调用、流操作、 确定最大值时不包括数据库查询等 脚本运行的时间。在 Windows 上不是这样 其中测量的时间是真实的。

因此,当您一次发送多封邮件时,使用Anti-Flood 插件是一个好主意。

但是,我认为更好的做法是将电子邮件存储在数据库中,并让 cronjob 每 Y 分钟从数据库发送 X 封邮件。这样一来,您就没有需要等待几分钟的加载脚本(如果页面重新加载,则存在重新发送的危险)。如果你使用像 Laravel 这样的框架,那么你可以使用内置的 mail-query 功能,它正是这样做的。

【讨论】:

    【解决方案2】:

    要发送批量电子邮件,您应该使用像 RabbitMQ 这样的代理服务。您必须创建 2 个队列,一个用于汇集电子邮件,另一个用于使用 Swiftmailer 发送电子邮件。每封邮件都会是一个 rabbitMq 消息。

    【讨论】:

    • 我们在一个每天发送数千封电子邮件的项目中成功地使用了这种方法。应用程序写入队列,然后忘记了它。 rabbitmq 消费者阅读请求并在有时间时发送电子邮件,
    • 如果你的回答有更多实质内容可以让发帖人妨碍你,我会支持你
    猜你喜欢
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2018-01-07
    相关资源
    最近更新 更多