通过PhpMailer异步发送电子邮件

6
我正在使用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调用的内联参数而不是php.ini中的全局更改。有人试过这个吗?

2个回答

22

方法错误。

PHPMailer并不是一个邮件服务器,而您要求它成为邮件服务器。SMTP是一种冗长的、啰嗦的协议,容易产生延迟和低吞吐量,并且绝对不适合在典型的网页提交交互期间发送电子邮件(这可能是BlackHatSamurai链接的问题所做的)。许多人都可以做到这一点,但不要被骗以为这是一个好的解决方案,绝对不要尝试自己实现MTA。

您链接的gmail示例正在使用SMTP发送到远程服务器,这将始终比本地提交慢。如果您通过sendmail(或 mail() - 实际上是相同的东西)提交到本地服务器并且需要超过0.1秒的时间,则说明您做错了什么。即使是SMTP到localhost也不会花费太长时间,向附近的智能主机发送邮件也不太可能太慢。

尝试使用线程后台处理事情是一个巨大的风险,绝对不是解决这个问题的正确方法 - 任何以这种方式实现的东西都会比一个正确的邮件服务器差得多。不要这么做。

正确的做法是安装一个本地邮件服务器,并使用PHPMailer将消息提交到其中。这种方法非常快(每秒数百封电子邮件),而且您无需做任何事情就可以使其工作,因为这是PHPMailer默认的工作方式。

邮件服务器将执行它应该执行的任务 - 将您的消息排队,处理连接问题、传递延迟、错误和您未考虑的所有其他问题。


非常感谢您详细的解释,回应太棒了!我在这个主题方面有点新手 - 您有关于选择/安装哪个邮件服务器的建议吗?我使用的是共享托管计划。不确定我的网络主机是否允许我安装自定义的邮件服务器。非常感谢! - rogerb
大多数Linux发行版使用Postfix,我更喜欢它而不是Exim。当然还有很多其他选择。如果您的ISP不允许您安装其中一个,他们可能已经提供了某些东西,或者附近有一个智能主机 - 请查看他们的文档,打开支持票证。如果他们没有提供,我建议安装新的服务提供商... - Synchro
1
感谢@Synchro。最终我使用了由我的托管提供商提供的默认邮件服务器,并注意到(带有时间戳)每封电子邮件大约需要2秒钟。所以我打电话给我的网络主机,他们说由于我使用的是共享托管计划,这种延迟是可以预期的(显然,他们的邮件服务器会发送到代理,然后排队再发送)。最后,我在我的php.ini中设置了“-O DeliveryMode=b”(http://blog.oneiroi.co.uk/linux/php/php-mail-making-it-not-suck-using-sendmail/),这产生了巨大的改变。现在电子邮件以后台模式发送,我的脚本返回时间为**0.16秒!** - rogerb
什么?这就是Sendmail属性的作用 - 只需在您的实例中设置它,无需触及库代码。 - Synchro
哦,我明白了。我之前误解了你的观点。谢谢澄清。 - rogerb
显示剩余3条评论

0
根据this所述,phpMailer不支持此类调用。您需要编写自己的线程类才能进行异步调用。请参阅pThreadsThread类。另外还有一种解决方案可以在这里找到。

感谢您的回复和提供的链接。我想知道这是否完全准确(最新的),因为phpMailer似乎允许使用sendmail作为传递机制。我将编辑我的问题并添加这些信息。 - rogerb
@rogerb,无论如何,您都必须重写Sendmail类以使用异步线程。 - BlackHatSamurai
使用智能主机怎么样? - Phil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接