用PHP向很多用户发送电子邮件的最有效方法是什么?

时间:2012-04-18 20:05:54

标签: php mysql performance email

我的网站会在有人PM(私信)时向我的用户发送电子邮件。它说的是“有人刚在SITE NAME上给你发了一条消息,登录查看”。

目前我的网站不是很受欢迎,所以我目前这样做的方式并不是性能问题:

    // code that sends pm here...

    // code that stores pm in messages table here...

    // notify user by emailing them right away
    mail($user_email, $subject, $message);

基本上每次发送PM时,都会执行邮件功能,并在现场立即发送邮件。因此,对于每发送100封邮件,mail()会被调用100次。

我期待我的网站越来越受欢迎,越来越多的用户会来PM,所以我认为我目前的做法会成为一场性能噩梦。所以我想这样做:

// get the last message that was accounted for by the last cron
$query = mysql_query(" SELECT `last_checked_id` FROM `settings` ");
$last_checked_id = mysql_fetch_array($query);


$user_emails = array();

// get all messages that were added to this table since the last time this cron ran
$query = mysql_query(" SELECT `recipient_id`, `message_id` FROM `messages` WHERE `message_id` > '$last_checked_id' ");

$i = 0;
while($row = mysql_fetch_array($query)) {

    if($i == 0) {
        // set this as the last message processed
        mysql_query(" UPDATE `settings` WHERE `last_checked_id` = '". $row['message_id'] ."' ");
    }

    // only put this user in the to email list if he hasn't been added already (since there can be multiple messages for the same user but we need to notify him only once) 
    if(!in_array($row['recipient_id'], $user_emails)) {
        array_push($user_emails, $row['recipient_id']);     
    }
}
$i++;

// send email to all users at one
mail(implode(',', $user_emails), $subject, $message);

我可以将此脚本设置为cron并让它每小时运行一次。所有电子邮件都是一次性发送的,邮件功能只被调用一次。唯一的缺点是,当用户收到PM时,不会立即通知用户,而是在一小时内收到通知。 但这不是什么大不了的事情,我可以忍受。

我的问题是:

  • 是cron方法明显更好的性能或增加可忽略
  • 这是大多数大型网站的做法吗?还是有更好的方法,一些已建立的图书馆可能会再见?

感谢。

3 个答案:

答案 0 :(得分:1)

您可以将邮件插入mysql表(emailoutgoing)

如果每3分钟运行一次cron作业,您就可以从表中获取未发送(100?)的电子邮件,发送和标记行发送。

答案 1 :(得分:0)

如果我理解正确,您会向每个人发送完全相同的电子邮件?在这种情况下,您应该使用密件抄送字段用于电子邮件地址,或者每个人都会看到其他收件人,但在这种情况下,您可能会遇到可能忽略您的电子邮件的反垃圾邮件引擎的问题,因为他们不会将其用户视为电子邮件的收件人(未找到in to或cc field)。

但是你应该考虑为每个用户发送个性化的电子邮件(如果你向发送邮件的人和/或部分邮件添加了详细的预览,他们会更加热切)

答案 2 :(得分:0)

首先,阅读Mike B评论中的链接。

其次,你的代码有一些有趣的失败模式 - 它可能会失败,将所有邮件标记为已发送,并且没有人会知道。关于CRON和其他无人值守进程(包括一般网站)的关键是你需要知道什么时候出错。我考虑将"更新"在您发送邮件之后,最后声明。进行某种日志记录,以便您可以跟踪正在进行的操作。

第三,请不要将此电子邮件发送给"至"中的所有这些人。领域 - 正如Miro所说,它是垃圾邮件诱饵,但它也向用户提供了比他们可能拥有的信息更多的信息 - 他们知道您网站上随机其他用户的电子邮件地址,他们恰好在一小时内收到了PM他们如果你正在建立一个约会网站或社交网络,那几乎肯定会让人生气。

最后,我工作过的其他有类似要求的网站往往会有#34;事件"表,由守护程序/服务样式进程监视。该守护进程将做出明智的决定。我们设计的解决方案适合在多线程甚至多台机器上运行,但实际上从不需要这样做。

所以,你可能会有一个"事件"表格如下:

eventID    eventDate    eventType     eventStatus     eventMeta
-------------------------------------------------------------------
1          1 Feb 2012        PM           NEW         <from>bob@banana.com</from><to>alice@passionfruit.com</to>
2          1 Mar 2012        PM           COMPLETE    <from>fred@pear.com</from><to>jennifer@avocado.com</to> 

守护程序不断扫描eventStatus为NEW的记录,将它们设置为&#34;正在进行&#34;,处理它们,然后将状态设置为完成。

这使您可以查看系统中正在进行的操作 - 如果记录是&#34;正在进行中&#34;一秒钟以上,事情就被打破了。如果&#34; NEW&#34;记录不断增长,并且#34;完成&#34;记录没有,有些东西被打破了。