通过PhpMailer异步发送电子邮件

时间:2015-09-23 15:10:16

标签: php email asynchronous phpmailer

我正在使用PHPMailer发送效果很好的电子邮件。但问题是,由于它同步发送电子邮件,后续页面加载需要很长时间。

我正在使用PhpMailer,如本例https://github.com/PHPMailer/PHPMailer/blob/master/examples/gmail.phps

所示

我想知道是否有办法使电子邮件传递异步。我对此进行了研究,发现sendmail可以选择将DeliveryMode设置为"后台模式" - 来源http://php.net/manual/en/function.mail.php

mail($to, $subject, $message, $headers, 'O DeliveryMode=b');

我想知道在PhpMailer中是否可以做类似的事情?有人有这个成功吗?

编辑: - (其他信息)似乎可以将PhpMailer配置为使用sendmail - https://github.com/PHPMailer/PHPMailer/blob/master/class.phpmailer.php 因此,我想知道是否可以某种方式利用它来启用后台交付。

/**
 * Which method to use to send mail.
 * Options: "mail", "sendmail", or "smtp".
 * @type string
 */
public $Mailer = 'mail';

/**
 * The path to the sendmail program.
 * @type string
 */
public $Sendmail = '/usr/sbin/sendmail';
/**
 * Whether mail() uses a fully sendmail-compatible MTA.
 * One which supports sendmail's "-oi -f" options.
 * @type boolean
 */
public $UseSendmailOptions = true;

/**
 * Send messages using $Sendmail.
 * @return void
 */
public function isSendmail()
{
    $ini_sendmail_path = ini_get('sendmail_path');
    if (!stristr($ini_sendmail_path, 'sendmail')) {
        $this->Sendmail = '/usr/sbin/sendmail';
    } else {
        $this->Sendmail = $ini_sendmail_path;
    }
    $this->Mailer = 'sendmail';
}

另外 - 显然有办法通过php.ini设置sendmail选项 http://blog.oneiroi.co.uk/linux/php/php-mail-making-it-not-suck-using-sendmail/

我更愿意将此作为api调用vs php.ini的内联参数,这样才不会发生全局变化。有人试过吗?

2 个答案:

答案 0 :(得分:17)

错误的做法。

PHPMailer不是邮件服务器,这是你要求它的。 SMTP是一种冗长,繁琐的协议,容易出现延迟和吞吐量缓慢,并且绝对不适合在典型的网页提交期间以交互方式发送(这是BlackHatSamurai可能正在做的问题)。许多人正是这样做的,但不要误以为它是一个很好的解决方案,并且绝对不会尝试自己实施MTA。

您链接到的gmail示例是使用SMTP到远程服务器,这将始终比在本地提交慢。如果您通过sendmail(或mail() - 它基本上是相同的事情)向本地服务器提交并且它花费的时间超过0.1秒,那么您就是在做一些非常错的。即使是本地主机的SMTP也不会花费更长的时间,发送到附近的智能主机也不会太慢。

尝试使用线程来处理背景是一种巨大的蠕虫病毒,而这种方式并不是解决这个问题的方法 - 与正确的邮件服务器相比,无论你以何种方式实现这种方式都会非常糟糕。不要这样做。

执行此操作的正确方法是安装本地邮件服务器,并使用PHPMailer将消息提交给它。这种方式非常快(每秒数百条消息),并且您必须精确地 nothing 才能使其正常工作,因为这是PHPMailer默认工作的方式。

邮件服务器将执行它应该做的事情 - 排队邮件,处理连接问题,交付延期,退回以及您未考虑的所有其他内容。

答案 1 :(得分:0)

根据this phpMailer不支持此类通话。您必须编写自己的线程类才能进行异步调用。请参阅pThreadsThread课程。找到另一个解决方案here