PHP 批量发送电子邮件

4

可能是重复问题:
使用PHP发送大批量电子邮件

我有一个PHP脚本,可以向我的数据库中的所有用户发送单独的电子邮件,例如月度/周讯。

我正在使用以下代码:

$subject = $_POST['subject'];
$message = $_POST['message'];

// Get all the mailing list subscribers.
$query = $db->prepare("SELECT * FROM maildb");
$query->execute();

// Loop through all susbcribers, and send and individual email.
foreach ($query as $row) {

    // Setting maximum time limit to infinite.
    set_time_limit(0);

    $newMessage = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
        </head>
        <body>';

    // Search for the [unsubscribe] tag and replace it with a URL for the user to unsubscribe
    $newMessage .= str_replace("[unsubscribe]", "<a href='".BASE_URL."unsubscribe/".$row['hash']."/".$row['email']."'>unsubscribe</a>", $message);

    $newMessage .= '</body></html>';

    $to = $row['email'];

    // Establish content headers
    $headers = "From: info@domain.com"."\n";
    $headers .= "Reply-To: bounce@domain.com"."\n";
    $headers .= "X-Mailer: PHP v.". phpversion()."\n";
    $headers .= "MIME-Version: 1.0"."\n";  
    $headers .= "Content-Type: text/html; charset=iso-8859-1"."\n";
    $headers .= "Content-Transfer-Encoding: 8bit;";

    mail($to, $subject, $newMessage, $headers); // Send email to each individual user

}

这段代码在一个非常小的数据库中运行得很好... 我最近用20万用户填充了我的测试数据库,显然这个脚本失败了,内存溢出并且崩溃了...

我知道这是发送如此多电子邮件的一种糟糕方式,因此我想请教您更高效的方法!

非常感谢!


1
首先要做的事情是:像毒瘤一样抛弃mail(),并切换到一个真正的邮件包,例如SwiftmailerPHPMailer - Marc B
5个回答

2

您遇到的超时问题是由于Apache和PHP执行限制引起的。

您需要将其作为CLI应用程序运行,并使用set_time_limit(0);

在控制台中直接输入php /path/to/app/script.php之类的命令。

如果您没有SSH访问权限,则可以像这样使用shell_exec运行:

shell_exec("php /path/to/app/script.php > /dev/null 2>/dev/null &");

这将确保调用它的脚本不会一直挂起,直到它完成。

1

你可以设置Cron调度程序每分钟或一定时间间隔运行一次。脚本的每次执行将从数据库中选取几条记录并将它们从数据库中删除或设置为无效。向一小部分人发送电子邮件,然后让脚本停止。另一个cron调用将选取其他一些记录并停止。此外,您还可以利用exec()。


1

将它们分批处理,这样你每次只发送几个邮件,你的数据库中有一个字段检查每月是否已经向该用户发送了通讯,当通讯发送给该用户后,就对该字段进行标记,然后可以继续运行脚本直到每个人都收到为止。


0

我宁愿将用户使用implode函数合并成一个变量,然后一次性发送电子邮件。

$to_array = array();

foreach ($query as $row) {

  $to_array[] = $row['email'];

}

$to = implode(', ', $to_array);

//do your email stuff here

 mail($to, $subject, $newMessage, $headers); // Send email to all users at once

希望这可以帮到你 :-)

1
如果您遇到执行时间问题,请添加以下代码:ini_set('max_execution_time', 3000); 在这种情况下,3000代表秒数,即5分钟。 - mithilatw

0

请查看此网址:--

使用PHP发送大量电子邮件

首先,使用PHP自带的mail()函数并不是最佳解决方案。它很容易被标记为垃圾邮件,并且您需要设置标题以确保正确发送HTML电子邮件。至于代码片段是否有效,它确实有效,但我怀疑您是否能够在其中正确地获取HTML代码,除非指定额外的标题

我建议您查看SwiftMailer,它支持HTML、不同的mime类型和SMTP身份验证(这样更不可能将您的邮件标记为垃圾邮件)。


请查看此网址,它对您非常有用:https://dev59.com/6HNA5IYBdhLWcg3wBpHs - Abid Hussain
请参阅https://dev59.com/SFTTa4cB1Zd3GeqPwdsQ。 - Abid Hussain
谢谢您的回答,我会阅读这些文章。SwiftMailer也会卡住...在/home/content/lib/classes/Swift/Mime/Headers/MailboxHeader.php的307行超过了30秒的最大执行时间。 - qalbiol
你可以通过设置 ini_set('memory_limit', '1024M') 来增加最大执行限制。 - Abid Hussain

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