如何使用swift_mailer修复/避免此smtp错误?

时间:2012-06-08 14:32:41

标签: smtp send swiftmailer mailer

对不起,可能只是一个新手问题,但是在这里, 我有一个脚本循环过一堆(有时数千)成员发送电子邮件使用如下代码:

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

                $mailer = Swift_Mailer::newInstance($transport);
                $mailer->send($message);

它通常效果很好,但有时我会收到此错误: 预期的响应代码354,但代码为“250”,消息“250 2.1.5 ...收件人确定

我不知道smtp很好,所以我只能猜测发生的事情是发送邮件流程开始时预计会有354个代码,但是250封代码是从上一封发送的邮件中收到的 - 所以邮件收到了由于使用速度过快导致过载,我想我应该等待每封电子邮件真正完成(即等待250代码),然后再发送下一封。我不想在每封电子邮件后粘贴一个睡眠命令,那么是否有更好的方法来防止此错误?或者原因是什么?

由于

1 个答案:

答案 0 :(得分:1)

总结:

  1. 要做的主要更改:重复使用您的邮件连接,最好是创建邮件,因此只能根据需要进行,通常只需一次
  2. 检查如何实例化SwiftMailer并确认它是最佳方式
  3. 您的SwiftMailer类版本似乎有点陈旧(4.0.5),您可能会查看更新的版本
  4. 更详细:

    重新使用实例化对象。您每次都在重新创建邮件传输,从而导致开销。你不应该这样做。如果支持,您可以将batchSend()用于大量电子邮件。请参阅this question中的使用示例。一个应用的例子:

    $message = Swift_Message::newInstance(...)
      ->setSubject('A subject')
      ->setFrom(array('myfrom@domain.com' => 'From Me'))
      ->setBody('Your message')
    ;
    
    while(list($targetadd, $targetname) = each($targetlist))
    {
       $message->addTo($targetadd, $targetname);
    }
    
    $message->batchSend();
    

    请注意,batchSend()已为removed in 4.1.0 RC1 of SwiftMailer。据我虽然知道,它internally called send() in a loop,所以你应该能够与调用send()多次,但至少重用你的邮件传输,所以你不会告发&#39相同的效果;吨每次重新实例它(如果适用,还要创建消息)。

    official documentation的批量发送示例中,您可以使用带有

    的send()批量发送电子邮件
    // Create the Transport
    $transport = Swift_SmtpTransport::newInstance('localhost', 25);
    
    // Create the Mailer using your created Transport
    $mailer = Swift_Mailer::newInstance($transport);
    
    // Create a message
    $message = Swift_Message::newInstance('Wonderful Subject')
      ->setFrom(array('john@doe.com' => 'John Doe'))
      ->setBody('Here is the message itself')
      ;
    
    // Send the message
    $failedRecipients = array();
    $numSent = 0;
    $to = array('receiver@domain.org', 'other@domain.org' => 'A name');
    
    foreach ($to as $address => $name)
    {
      if (is_int($address)) {
        $message->setTo($name);
      } else {
        $message->setTo(array($address => $name));
      }
    
      $numSent += $mailer->send($message, $failedRecipients);
    }
    

    传输协议。另外需要注意的是,SwiftMailer是一个包装类。它的实际用途是你定义的内容。在您的情况下,您使用的是SMTP传输,这比Mail传输(mail()函数)更好,但可能不是最佳的传输。

    如果你明确想要使用它以及你拥有的环境,你就不会说,但是在linux环境中,你可以直接调用sendmail,例如

    $transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');
    

    这可以提供更好的表现。 SwiftMailer usage documentation中有关于不同传输的更多信息。

    类版本。根据您的评论,您使用的是4.0.5版本。当前版本为4.1.8.,自批量发送以来,有些内容已经更改,因此您可能也想检查一下。

    编辑:有关batchSend(),当前版本和手动链接的更新信息。