【问题标题】:fastest way to send mails using phpmailer smtp?使用 phpmailer smtp 发送邮件的最快方法?
【发布时间】:2014-10-12 18:57:46
【问题描述】:

我正在使用以下 phpmailer 功能发送 1000 多封邮件

<?php
function sendMail($sendTo,$Subject,$Body){

    require_once 'PHPMailer/PHPMailerAutoload.php';

    $mail = new PHPMailer;
    $mail->isSMTP();                                      
    $mail->Host = 'smtp.example.com;smtp.example.com';  
    $mail->SMTPAuth = true;                               
    $mail->Username = 'newsletter@example.com';           
    $mail->Password = 'password';                         
    $mail->SMTPSecure = 'ssl';                            
    $mail->Port = 465;                                    
    $mail->From = 'newsletter@example.com';
    $mail->FromName = 'xyz';
    $mail->WordWrap = 50;                                 
    $mail->isHTML(true);                                  

    $mail->addAddress($sendTo);               
    $mail->Subject = $Subject;
    $mail->Body = ( stripslashes( $Body ) );
    $mail->AltBody = 'Please Use a Html email Client To view This Message!!';

    if(!$mail->send()) {
        $return = 'Message could not be sent.';
        // echo 'Mailer Error: ' . $mail->ErrorInfo;
    } else {
        $return = 'Message has been sent!';
    }
    return $return;
}

这是我用来调用函数的代码

foreach ($emails as $email) {
 $subject = "sample subject";
 $body = "sample body";
 sendMail($email, $subject, $body);
}

$emails 数组的大小为 1000+ 有没有更快更好的方法来做到这一点?

【问题讨论】:

  • 有 - 使用 MTA(例如后缀)

标签: php email phpmailer


【解决方案1】:

您应该从reading the docs provided with PHPMailer 开始,在那里您可以找到this example

特别注意,确保您使用SMTPKeepAlive - 您可能会发现按域对列表进行排序以最大限度地重复使用连接。

正如 zerkms 所说,您应该提交到本地邮件服务器以获得最佳性能,但令人惊讶的是,在 PHPMailer 中使用 mailsendmail 选项并不总是比 SMTP 到 localhost 快,这主要是因为 postfix 的 sendmail 二进制文件会打开一个同步的无论如何都要通过 SMTP 连接到 localhost - postfix' 文档建议使用 SMTP 到 localhost 以获得最佳性能。

如果您要发送到本地主机,请不要使用身份验证或加密,因为开销不会为您带来任何好处,但如果您使用远程服务器,请在端口 587 上使用 tls,而不是在端口 465 上使用过时的 ssl .

通常要避免直接发送给最终用户 - PHPMailer 中的 SMTP 客户端有点笨 - 它根本不处理排队,因此任何具有灰名单或延迟交付以进行流量控制的域都将无法交付。最好的方法是对附近的 MTA 使用 SMTP,并将队列处理留给它。您也可以从中获得退回,因此您可以从列表中删除不良地址。

【讨论】:

  • 这很有帮助 :-) +1
【解决方案2】:

未经测试,但这应该可以工作。

基本上,它会重用原始对象(从而减少内存分配)。

require_once 'PHPMailer/PHPMailerAutoload.php';

class BatchMailer {

    var $mail;

    function __construct () {
        $this->mail = new PHPMailer;
        $this->mail->isSMTP();
        $this->mail->Host = 'smtp.example.com;smtp.example.com';
        $this->mail->SMTPAuth = true;
        $this->mail->Username = 'newsletter@example.com';
        $this->mail->Password = 'password';
        $this->mail->SMTPSecure = 'ssl';
        $this->mail->SMTPKeepAlive = true;
        $this->mail->Port = 465;
        $this->mail->From = 'newsletter@example.com';
        $this->mail->FromName = 'xyz';
        $this->mail->WordWrap = 50;
        $this->mail->isHTML(true);
        $this->mail->AltBody = 'Please use an HTML-enabled email client to view this message.';
    }

    function setSubject ($subject) {
        $this->mail->Subject = $subject;
    }

    function setBody ($body) {
        $this->mail->Body = stripslashes($body);
    }

    function sendTo ($to) {
        $this->mail->clearAddresses();
        $this->mail->addAddress($to);

        if (!$this->mail->send()) {
            // echo 'Mailer Error: ' . $this->mail->ErrorInfo;
            return false;
        } else {
            return true;
        }
    }

}

$batch = new BatchMailer;

$batch->setSubject('sample subject');
$batch->setBody('sample body');

foreach ($emails as $email) {
    $batch->sendTo($email);
}

【讨论】:

  • 您的更改如何解决“最快”的问题?你仍然是一个接一个地发送消息,这里最慢的部分是同步网络 IO。
  • @zerkms PHPMailer 类的单一初始化减少了几十个函数调用和内存分配。这是执行速度的一个很容易测量的差异。我对他的实现知之甚少,无法建议异步操作,他也没有要求替代库。
  • 没错。但是,如果您比较您的代码和原始代码的执行,您将不会注意到差异。仅仅因为新对象的创建与数百毫秒的 SMTP IO 相比简直是无法比拟的。我同意只创建一次对象是有意义的,我的观点是它不会改变任何东西。如您所知,当有人说他们想在滑板上与 F1 bolid 竞争时,最好的建议是让他们使用另一个 F1,而不是简单地安装另一个轮子(或给滑板涂上另一种华丽的颜色)。
  • 你是对的。在这种情况下,我谈论的是代码执行性能,而不考虑网络。实际上我不确定是否可以在这里应用异步,因为他使用 SMTP 帐户在远程服务器上发送邮件。我在@Synchro 的回复中添加了 SMTPKeepAlive 标志,因为这将大大减少网络开销。
  • 自从您第一次发表评论以来,您的观点非常明确。也许我还不是很清楚。我知道所涉及的网络延迟,但是这个问题询问了如何使他的 PHPMailer 代码实现更快,而不是用 C++ 或本地邮件服务器设计一个全新的系统。
【解决方案3】:

通过 cgi 将函数拖放到 c++ 中。一个 c++ 邮件程序将比首先访问整个 http 框架要强大得多。 http://www.cplusplus.com/forum/windows/86562/ 但是 PhP 已经为它的关联数组使用了哈希表,所以你不会再用哈希表来提高速度了。所以你真的在你的网络框架中达到了极限。 将其放到系统级函数中,c 是您最快/最精简的选择。 除非你真的很擅长汇编语言。

【讨论】:

  • 这真的很无用。
  • 这无疑是“最快的方法”。您的情况可能不值得,但如果您想要最大速度,这是唯一的途径。
  • @Brad S:“这是唯一的途径”——如果问题是关于高性能计算,那就对了。然后确实切换 php -> C(++) 是有意义的。在这种情况下,瓶颈是网络 IO,而不是 CPU,因此优化不慢的东西是没有意义的。
  • 在我的辩护中,等待时间在 c++ 驱动的堆栈上会稍微少一些。您仍然需要考虑 OSI 上的几个层次。 C++ 就像 Honey Badder,它不在乎。 :)
猜你喜欢
  • 1970-01-01
  • 2018-09-10
  • 2017-10-05
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多