如何解决通过phpmailer发送电子邮件时,IF语句上的PHP异常行为具有IF和ELSE的输出
我要呈现的脚本很难理解,但是下面我将解释基本概念。
<?PHP
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
require_once 'apps/PHPMailer/src/Exception.PHP';
require_once 'apps/PHPMailer/src/PHPMailer.PHP';
require_once 'apps/PHPMailer/src/SMTP.PHP';
include_once('apps/HTMLDOMParser/simple_html_dom.PHP');
require_once("../db.PHP");
function clear($var) {
$var = NULL;
unset($var);
}
// Time when emails were sent last time
$result_laststamp = $conn->prepare("SELECT sent FROM nl_campaigns_emails ORDER BY sent DESC LIMIT 1",array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_laststamp->execute();
if($result_laststamp->rowCount() > 0) {
while($row_laststamp = $result_laststamp->fetch(PDO::FETCH_ASSOC)) {
// data for first qeued campaign
$result_campaign = $conn->prepare("SELECT id,name,text,amount,period,smtp,user FROM nl_campaigns WHERE status='1' ORDER BY id ASC LIMIT 1",array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_campaign->execute();
if($result_campaign->rowCount() > 0) {
while($row_campaign = $result_campaign->fetch(PDO::FETCH_ASSOC)) {
// SMTP Data
if($row_campaign['smtp']==1 && $row_campaign['user']>0) {
$result_smtp = $conn->prepare("SELECT * FROM admin_logins WHERE id=:id LIMIT 1",array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_smtp->execute(array(":id"=>$row_campaign['user']));
if($result_smtp->rowCount() > 0) {
while($row_smtp = $result_smtp->fetch(PDO::FETCH_ASSOC)) {
// Check if its time to send next group of emails
if($row_laststamp['sent'] < (time()-($row_campaign['period']*3600))) {
// get email addresses,send,and edit timestmap in db when they were sent
$result_emails = $conn->prepare("SELECT id,email FROM nl_campaigns_emails WHERE (id_campaign=:id_campaign AND sent='0') ORDER BY id ASC LIMIT ".$row_campaign['amount'],array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_emails->execute(array(":id_campaign"=>$row_campaign['id']));
if($result_emails->rowCount() > 0) {
$array_email_ids = array();
while($row_emails = $result_emails->fetch(PDO::FETCH_ASSOC)) {
try {
$mail = new PHPMailer(true);
$mail->CharSet = 'UTF-8'; // UTF8 Encoding
$mail->Encoding = 'base64'; // Needs to be set with UTF8
//$mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output
$mail->isSMTP(); // Send using SMTP
$mail->Host = "smtp.somedomain.com"; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = "noreply@somedomain.cz"; // SMTP username
$mail->Password = "somepassword"; // SMTP password
$mail->SMTPSecure = "tls";
$mail->Port = 587; // TCP port to connect to,use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
//Sender
$mail->setFrom($row_smtp['email'],'somename');
$mail->addReplyTo('info@somedomain.cz','somename');
$mail->Sender = 'noreply@somedomain.cz';
// Recipient
$mail->addAddress($row_emails['email']);
// Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg','new.jpg'); // Optional name
$bottom_text = "<p align=center style=\"font-size:11px; font-family:Arial; color:#8b8b8b;\">This email was sent to address <a href=\"mailto:".$row_emails['email']."\">".$row_emails['email']."</a>.<br>";
$bottom_text .= "To unsubscribe you can click to <a href=\"http://www.somedomain.cz/unsubscribe.PHP?email=".$row_emails['id']."\">unsubscribe</a>.</p>";
$bottom_text .= "<img src=\"http://www.somedomain.cz/view.PHP?id_campaign=".$row_campaign['id']."&id_email=".$row_emails['id']."\" style=\"visibility: hidden;\">";
// YOUTUBE LINK
$text = new simple_html_dom();
$text->load($row_campaign['text']);
foreach($text->find('iframe') as $element) {
$youtubeid = substr($element->src,strrpos($element->src,"/")+1);
// Create image instances
$video = imagecreatefromjpeg('https://img.youtube.com/vi/'.$youtubeid.'/maxresdefault.jpg');
$button = imagecreatefrompng('../images/youtube_play.png');
$video = imagescale($video,$element->width,$element->height);
$button = imagescale($button,imagesx($video)/7.5);
imagecopy($video,$button,imagesx($video)/2-imagesx($button)/2,imagesy($video)/2-imagesy($button)/2,imagesx($button),imagesy($button));
// Output and free from memory
imagejpeg($video,"../images/campaigns/videos/".$youtubeid.".jpg",95);
imagedestroy($video);
imagedestroy($button);
unset($video);
unset($button);
$element->outertext = '<a href="https://www.youtube.com/watch?v='.$youtubeid.'" target="_blank"><img src="http://www.somedomain.cz/images/campaigns/videos/'.$youtubeid.'.jpg" width="'.$element->width.'" height="'.$element->height.'"></a>';
}
$row_campaign['text'] = (string)$text;
$text->clear();
clear($text);
// URL LINK FOR CLICKER ANALYZER
$doc = new simple_html_dom();
$doc->load($row_campaign['text']);
foreach ($doc->find('a') as $a) {
$a->href = 'http://www.somedomain.cz/clicker.PHP?id_campaign='.$row_campaign["id"].'&id_email='.$row_emails["id"].'&url='.urlencode($a->href);
}
$row_campaign['text'] = (string)$doc;
$doc->clear();
clear($doc);
// Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $row_campaign['name'];
$mail->Body = $row_campaign['text'].$bottom_text;
$mail->AltBody = strip_tags($row_campaign['text']);
// MessageID
$data = array(
'campaign_id' => str_pad($row_campaign['id'],6,'0',STR_PAD_LEFT),'email_id' => str_pad($row_emails['id'],11,'sent' => time(),);
$messageId = '<'.base64_encode(json_encode($data)).'@www.somedomain.cz>';
$mail->MessageID = $messageId;
$mail->addCustomHeader('In-Reply-To',$messageId);
clear($data);
// SEND Email
$mail->send();
}
catch (Exception $e) {
echo "Emails were not send because: {$mail->ErrorInfo}";
die();
}
// ADD sent email to array
array_push($array_email_ids,$row_emails['id']);
// UPDATE the "sent" stamp
$update = $conn->prepare("UPDATE nl_campaigns_emails SET sent=:sent WHERE id=:id");
try { $update->execute(array(":id"=>$row_emails['id'],":sent"=>time())); }
catch(Exception $error) { die($error->getMessage()); }
clear($update);
clear($mail);
}
clear($result_emails);
// CHECK IF STATUS Could BE CLOSED
$result_emails_sent = $conn->prepare("SELECT id FROM nl_campaigns_emails WHERE (id_campaign=:id_campaign AND sent='0') ORDER BY id",array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$result_emails_sent->execute(array(":id_campaign"=>$row_campaign['id']));
if($result_emails_sent->rowCount() == 0) {
$update = $conn->prepare("UPDATE nl_campaigns SET status=:status WHERE id=:id");
try { $update->execute(array(":status"=>3,":id"=>$row_campaign['id'])); }
catch(Exception $error) { die($error->getMessage()); }
clear($update);
}
clear($result_emails_sent);
// Print the result
echo "<div style=\"color:#1b8d3d; text-align:center; font-size:25px; font-family:Arial;\">Sent total: ".count($array_email_ids)." emails.</div>";
echo "<center><a href=emailing.PHP style=\"color:black; text-align:center; font-size:25px; font-family:Arial; text-decoration:none;\">REFRESH</a></center>";
}
}
else {
echo "<div style=\"color:#1b8d3d; text-align:center; font-size:25px; font-family:Arial;\">Next emails can be send at: ".date("j.n.Y H:i:s",$row_laststamp['sent']+($row_campaign['period']*3600))."</div>";
echo "<center><a href=emailing.PHP style=\"color:black; text-align:center; font-size:25px; font-family:Arial; text-decoration:none;\">REFRESH</a></center>";
die();
}
}
}
else { die("error resolving SMTP"); }
clear($result_smtp);
}
}
clear($result_campaign);
}
else {
echo "<div style=\"color:#1b8d3d; text-align:center; font-size:25px; font-family:Arial;\">No campaign is running</div>";
echo "<center><a href=emailing.PHP style=\"color:black; text-align:center; font-size:25px; font-family:Arial; text-decoration:none;\">REFRESH</a></center>";
die();
}
}
}
clear($result_laststamp);
clear($conn);
?>
该脚本看起来非常庞大,但最终它的逻辑很简单:
- 获取上次发送电子邮件的时间(例如$ lastTimeSent)
- 获取打开的排队活动的数据(例如$ dataCampaign)
- 获取用于发送电子邮件的SMTP数据(例如$ SMTP)
- 检查当前时间戳记time()是否大于$ lastTimeSent + allowed_period(因为我允许每20分钟发送200封电子邮件)
- 循环PHPmailer,分别发送电子邮件(每次添加一封电子邮件发送)
问题是,如果我在不允许的时间段内运行脚本(因此我没有遵循20分钟内发送200封电子邮件的规则),则一切正常,脚本会将其评估为false:
if($row_laststamp['sent'] < (time()-($row_campaign['period']*3600)))
$row_laststamp['sent'] is the timestmap of last email sent ($lastTimeSent)
$row_campaign['period'] is allowed period to send the email (value is actually 0.33 as in hours its 20 minutes),and im multiplying it by 3600 to recalculate to seconds so I can compare
- 因此,从根本上讲,它仅会跳出并执行ELSE语句中的操作,因为它具有逻辑性和良好的行为
但是,当im超出周期,因此同一条语句的评估结果为TRUE时,就会发生非常奇怪的行为。 该脚本将按其应有的状态循环并发送电子邮件,但是实际上不是发送200封电子邮件(其值为$ row_campaign ['amount']的值),而是实际发送64封(有时65封电子邮件),然后它不会 回显已发送总计:“。count($ array_email_ids)。” 电子邮件应符合逻辑,但还会再次显示ELSE输出* 下一封电子邮件可以发送至:“。date(“ jnY H:i:s“,$ row_laststamp ['sent'] +($ row_campaign ['period'] 3600))。 。
所以我正在处理它立即显示IF和ELSE输出的问题... 换句话说,当语句* if($ row_laststamp ['sent'] 3600))) 为TRUE时,它将部分运行try {}的循环(200次中只有65次),然后仍然显示ELSE {} ...
但是!!!如果我删除/注释$ mail-> send()行;然后所有的作品按预期! (当然,除非发送电子邮件)。
我正在检查内存状态,如果我没有走出内存,发现最终循环的最大内存约为24MB(当limnit设置为256MB时),设置120s时执行时间也约为10秒。
因此,基本上,每次只发送一次时,PHPMailer不会循环发送200封以上的电子邮件吗?
我不介意将它们全部发送在一起而不是循环发送,但是我不希望在电子邮件的“ TO”标头中看到它们,如果我改为使用密件抄送,那么(至少在gmail中)它将跳转为垃圾邮件
有什么想法吗?
编辑: 我简化了脚本,根据https://github.com/PHPMailer/PHPMailer/wiki/Sending-to-lists进行了调整 我也确实放置了调试器 $ mail-> SMTPDebug = SMTP :: DEBUG_SERVER; 以查看发生了什么,并且有趣的是,从客户端到服务器的消息突然停止在中间...服务器无响应,因此传输仅在中间停止... 最后一行甚至还没有结束,只是: 2020-09-02 17:06:40客户端->服务器:NTI1MjUyNTNGaWRfY2FtcGFpZ24lMjUyNTI1MjUyNTI1MjUyNTI1MjUyNTI1MjUyNTI1MjU 因此通信只是无缘无故地停止,没有服务器回复它是否已发送,什么都没有... 有人有主意吗?
解决方法
所以最后的错误确实是我没有在每个send()之后清除收件人, 因此,第一封电子邮件已发送给1个收件人,并且每个循环都添加了1个,但之前的循环未清除... 每次循环解决问题后清除收件人
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。