I am trying to send emails to mutiple people with different bodies using one code, using PHPMailer via SMTP. My code is as follows :
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
require_once("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->Host = "xxxxxxxx";
$mail->SetFrom('xx#xxx.com');
$mail->Subject = "System Change";
$add = array("a", "b", "c");
foreach ( $add as $address ) {
$current = clone $mail;
if ( $address == 'a' )
{
$current->AddAddress('xx#xx.com');
$current->MsgHTML("Message1");
$current->send();
}
if ( $address == 'b' )
{
$current->AddAddress('xx#xx.com');
$current->MsgHTML("Message2");
$current->send();
}
if ( $address == 'c' )
{
$current->AddAddress('xx#xx.com');
$current->MsgHTML("Message3");
$current->send();
}
}
exit;
if($mail->Send())
{ echo "SUCCESSFUL"; }
else echo "ERROR IN SENDING MAILS";
exit;
}
?>
The issue is it is sending mails but only sending the first 2, and then displaying a timeout error. Is there any setting that I need to change or is it a problem with my code? Have edited it in many ways but it ends up sending only 2 mails instead of 3. Appreciate any help :) Thanks!
This will likely solve your issue, there is no need to clone the PHPMailer object.
I have sent hundreds of emails at once using this method with no timeout issues.
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
set_time_limit(120);
require_once("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->Host = "xxxxxxxx";
$mail->SetFrom('xx#xxx.com');
$mail->IsHTML(true);
$mail->Subject = "System Change";
$add = array("a", "b", "c");
foreach ( $add as $address ) {
$mail->clearAttachments();
$mail->clearAllRecipients();
if ( $address == 'a' )
{
$mail->AddAddress('xx#xx.com');
$mail->Body("Message1");
$mail->send();
}
if ( $address == 'b' )
{
$mail->AddAddress('xx#xx.com');
$mail->Body("Message2");
$mail->send();
}
if ( $address == 'c' )
{
$mail->AddAddress('xx#xx.com');
$mail->Body("Message3");
$mail->send();
}
}
if($mail->send()) echo "SUCCESSFUL";
else echo "ERROR IN SENDING MAILS";
exit;
}
Add the following line of code after the opening of the foreach loop
set_time_limit(60);
With this line of code, you give every mail 60 seconds to be sent. This number can be as high as you want. But I should try to keep it as low as possible
You are resetting the timelimit to 60 seconds every time this piece of code is run. Resetting it back to zero.
Base your code on the mailing list example provided with PHPMailer. Generally you don't ever want to be doing this kind of thing on a page load via a web server - run it from cron where timeouts are not an issue.
Related
The script im going to present is quite dificult to understand, but I will explain the basic idea bellow.
<?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 ".$row_emails['email'].".<br>";
$bottom_text .= "To unsubscribe you can click to unsubscribe.</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, 0, 0, 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 = '<img src="http://www.somedomain.cz/images/campaigns/videos/'.$youtubeid.'.jpg" width="'.$element->width.'" height="'.$element->height.'">';
}
$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, '0', STR_PAD_LEFT),
'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>REFRESH</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>REFRESH</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>REFRESH</center>";
die();
}
}
}
clear($result_laststamp);
clear($conn);
?>
the script looks quite huge, but at the end its simple logic:
get the last time emails were sent (for example $lastTimeSent)
get the data of the opened queued campaign (for example $dataCampaign)
get SMTP data to be used for sending emails (for example $SMTP)
checks if current timestamp time() is bigger then $lastTimeSent+allowed_period (because Im allowed to send 200 emails every 20mins)
loop the phpmailer, send emails separately (each time add one email to send)
and the problem is, that if I run the script inside nonallowed time period (so im not following rule of 200 emails in 20 mins), all works fine and script will evaluate this as 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
so basicaly will jump and do stuff only from ELSE statement as its logical and its OK behaviour
However, when im outsode of the period so the same statement would evaluate as TRUE, the very strange behaviour happens.
The script will be looping and sending emails as it should, however instead of sending 200 emails as its the value of $row_campaign['amount'], it actually sends 64 (sometimes 65 emails) and then it wont echo Sent total: ".count($array_email_ids)." emails as it should logicaly, but also shows again the ELSE output *Next emails can be send at: ".date("j.n.Y H:i:s", $row_laststamp['sent']+($row_campaign['period']3600))..
So Im dealing with the problem that its shows the IF and ELSE output at once...
In other words, when statement *if($row_laststamp['sent'] < (time()-($row_campaign['period']3600))) is TRUE, it will partialy run the loop of try {} (only 65 times out of 200) and then shows the ELSE {} anyway...
BUT !!! if I remove/comment the line $mail->send(); then ALL works as expected !!!!! (unless emails are sent of course).
I was checking the memory status if im not getting out of memory and found out the maximum in final loop is about 24MB (when limnit is set to 256MB), also execution time is around 10second when I have set 120s.
so basicaly PHPMailer wont send more then 200 emails in loop when sending just one each time?
I wouldnt mind to send them all together and not looping it, however i dont want them to be seen in "TO" header of email, and if I use BCC instead, then (at least in gmail) it jumps to spam.
Any ideas?
EDIT:
I have simplified the script, made the adjustment according to https://github.com/PHPMailer/PHPMailer/wiki/Sending-to-lists
also i did place the debugger $mail->SMTPDebug = SMTP::DEBUG_SERVER; to see whats happening, and its interesting that the message from client to server suddently stop in the middle... no responce from the server, so the transfer just stops in the middle...
the very last line is not even finished and it just:
2020-09-02 17:06:40 CLIENT -> SERVER: NTI1MjUyNTNGaWRfY2FtcGFpZ24lMjUyNTI1MjUyNTI1MjUyNTI1MjUyNTI1MjUyNTI1MjU
so the comunication just stops from no reason, no server reply that its sent or not, nothing...
anyone has an idea?
so the error at the end was realy that I was not clearing recipients after each send(),
therefore first email was send to 1 recipient and each loop was 1 added but previous was not cleared...
clearing recipients after each loop fixed the problem
I am sending emails using PHPmailer. As of now, I am successful in sending email to one address. Now, I want to send multiple emails in just one click.
PROBLEM: I have tried to use some loops below to send multiple email but I get wrong outpout. Yes, it sends email but to only one address, and the email address is getting all of the emails that are supposed to be emailed to other emails.
For example, when I send 17 emails, those 17 emails are sent to only one address. The emails should be sent according to the addresses in the database, with corresponding unique attachments. Example: abc#gmail.com should have abc.pdf attached, and 123#gmail.com should have 123.pdf attached.
I think it's in the loop. Please help me figure it out. Thanks.
require_once('phpmailer/class.phpmailer.php');
include("phpmailer/class.smtp.php");
$mail = new PHPMailer();
$body = file_get_contents('phpmailer/body.html');
$body = preg_replace('/\/b]/','',$body);
$file ='phpmailer/mailpass.txt';
if($handle = fopen($file,"r")){
$contentpass = fread($handle,'15');
fclose($handle);
}
$mail->IsSMTP();
$mail->Host = "smtp.gmail.com";
$mail->SMTPDebug = 1;
$mail->SMTPAuth = true;
$mail->SMTPSecure = "tls";
$mail->Host = "smtp.gmail.com";
$mail->Port = 587;
$mail->Username = "email#gmail.com";
$mail->Password = $contentpass;
$mail->SetFrom("email#gmail.com", "Subject");
$mail->AddReplyTo("email#gmail.com","Subject");
$mail->Subject = "Subjects";
$mail->AltBody = "Subject";
$mail->MsgHTML($body);
$file='current_schoolyear.txt';
if($handle = fopen($file,"r"))
{
$content = fread($handle,'9');
fclose($handle);
}
$input = addslashes($_POST['depchair']);
$email = "select email_address from sa_student where schoolyear = '$input'";
if ($p_address=mysql_query($email))
{
while($row = mysql_fetch_assoc($p_address))
{
$mail->AddAddress($row['email_address']);
$input = addslashes($_POST['depchair']);
$control = "select control_no from sa_student where schoolyear = '$input'";
if($ctrl=mysql_query($control)){
$ctrl_no = mysql_result($ctrl, 0);
$mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
}
else
{
echo "No attached document.";
}
if(!$mail->Send()) {
$message = "<div class=\"nNote nFailure\" >
<p>Error sending email. " . $mail->ErrorInfo ."</p>
</div>";
} else {
$message = "<div class=\"nNote nSuccess\" >
<p> Email have been sent to the examinees in ".$input_depchair. "! </p>
</div>";
}
}
}
else
{
echo (mysql_error ());
}
UPDATED CODE: After running the code below, I was able to send an email and with the correct attachment. However, there was only ONE email sent (the last email address in the database), and the rest of the emails were not sent.
$input = addslashes($_POST['depchair']);
$email = "select email_address, control_no from sa_student where schoolyear = '$input'";
if ($p_address=mysql_query($email))
{
while($row = mysql_fetch_assoc($p_address))
{
$cloned = clone $mail;
$cloned->AddAddress($row['email_address']);
$cloned->AddAttachment("fpdf/pdf_reports/document/".$row['control_no'].".pdf");
if(!$cloned->Send()) {
$message = "<div class=\"nNote nFailure\" >
<p>Error sending email. " . $mail->ErrorInfo ."</p>
</div>";
} else {
$message = "<div class=\"nNote nSuccess\" >
<p> Email have been sent to the examinees in ".$input_depchair. "! </p>
</div>";
}
unset( $cloned );
}
}
else
{
echo (mysql_error ());
}
After you send an email $mail->Send(), execute this:
$mail->ClearAllRecipients();
in your while loop.
So your basic while loop structure looks like this:
while($row = mysql_fetch_assoc($p_address)){
$mail->AddAddress($row['email_address']);
$mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
$mail->send();
$mail->ClearAllRecipients();
$mail->ClearAttachments(); //Remove all attachements
}
Within your loop, create a clone of the $mail object - before you add the recipient and attachment - then use the clone to send the email. The next loop iteration will create a new clone free of the previous address and attachment:
while($row = mysql_fetch_assoc($p_address)) {
$cloned = clone $mail;
$cloned->AddAddress($row['email_address']);
// add attchment to $cloned, etc.
if ( $cloned->send() ) { /* etc */ }
unset( $cloned );
}
This will "clear" your per-iteration changes (like address, attachment, etc) without you having to reenter config properties (like, from, host, etc.)
Addendum:
Your attachments will likely be all the same because you're not fetching new results for these lines (within your loop):
$input=addslashes($_POST['depchair']);
$control = "select control_no from sa_student where schoolyear = '$input'";
if ($ctrl=mysql_query($control)) {
$ctrl_no = mysql_result($ctrl, 0);
$mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
}
$ctrl_no will always return the same result because (I'm assuming) $_POST['depchair'] does not change - thus $input, $control, $ctrl, and $ctrl_no all remain (effectively) the same for each loop. You need to find whatever it is your actually intend to be the $ctrl_no for each loop - right now you're using the same one over and over.
The following query could probably help:
// replace
// $email = "select email_address from sa_student where schoolyear = '$input'";
// with:
$students_query = "select email_address, control_no from sa_student where schoolyear = '$input'";
// then
// if ($p_address=mysql_query($email)) {
// while($row = mysql_fetch_assoc($p_address)) {
// becomes
if ( $students=mysql_query($students_query) ) {
while ( $row = mysql_fetch_assoc( $students ) ) {
// so that finally, etc
$cloned->AddAddress($row['email_address']);
$ctrl_no = $row['control_no'];
This pulls both the student email address and their control_no in the same query, making sure they stay associated with each other through the loop. You can then get rid of the second mid-loop query, since all the results you need were pulled in the first out-of-loop query. The above isn't all the code you need to change, just the critical parts.
I have this weird error coming up from phpmailer (Version: 5.1 ):
exception 'phpmailerException' with message 'Could not instantiate mail function.' in C:\Inetpub\vhosts\mydomain\httpdocs\myscript\protected\components\phpmailer\class.phpmailer.php:687 Stack trace: #0 C:\Inetpub\vhosts\mydomain\httpdocs\myscript\protected\components\phpmailer\class.phpmailer.php(578): PHPMailer->MailSend('Date: Wed, 2 Oc...', '--b1_3c2b33630c...')
FYI: I am trying to send a zip file that's around 4.5MB big. But before that the script generates around 50 PDFs and adds them/creates the zip file which then gets attached to a phpmailer object and sent. (I am not using SMTP).
I know this has been asked before.. but the solutions I have found are all based on linux server involving increasing the limit on postfix.
But how do I solve this issue if the site is hosted on a windows machine ? I have plesk control panel.
Thanks in advance for your help.
[EDIT]
Here's the code snippet just incase it helps:
foreach($vars as $PDFKEY)
{
if($PDFKEY != null)
{
if((int)$PDFKEY > 0 )
{
$filename = $this->CreatePDF($PDFKEY);
$emailarr[$PDFKEY['email']][] = $filename;
$emailIdarr[$company->email][] = $PDFKEY['email'];
}
}
}
sleep(20);
//print_r($emailarr);die;
$emailTemplate = Yii::app()->params['EmailTemplate'];
$body = file_get_contents($emailTemplate);
$body = eregi_replace("[\]",'',$body);
try
{
$mail = new PHPMailer(true);
if(strtolower(Yii::app()->params['SMTPStatus']) == "enabled")
{
$mail->IsSMTP(); // telling the class to use SMTP
$mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent
$mail->Host = Yii::app()->params['SMTPHost']; // sets the SMTP server
$mail->Port = Yii::app()->params['SMTPPort']; // set the SMTP port for the GMAIL server
if(strtolower(Yii::app()->params['SMTPAuthStatus']) == "enabled")
{
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Username = Yii::app()->params['SMTPUsername']; // SMTP account username
$mail->Password = Yii::app()->params['SMTPPassword']; // SMTP account password
}
}
$mail->SetFrom(Yii::app()->params['EmailSendFrom']);
$mail->AddReplyTo(Yii::app()->params['EmailSendFrom']);
$mail->Subject = Yii::app()->params['EmailSubject'];;
$savePath = Yii::app()->params['PdfSavePath'];
$mail->AddBCC(trim(Yii::app()->params['EmailBCC']));
$b = true;
$toEmailAdded = array();
$ccEmailAdded = array();
$companyCCEmailAdded = array();
foreach($emailarr as $email=>$attachmentArr )
{
try
{
if(!in_array($email, $toEmailAdded))
{
$toEmailAdded[] = $email;
$mail->AddAddress($email);
}
if(isset($_POST['emailcc']) && strlen($_POST['emailcc']) > 0)
{
if(!in_array($_POST['emailcc'], $ccEmailAdded))
{
$ccEmailAdded[] = trim($_POST['emailcc']);
$mail->AddCC(trim($_POST['emailcc']));
}
}
$companycc = trim($emailNamearr[$email]['companyccemail']);
if(isset($companycc) && strlen($companycc) > 0)
{
foreach(explode(',',trim($companycc)) as $cc)
{
if(!in_array($cc, $companyCCEmailAdded))
{
$companyCCEmailAdded[] = trim($cc);
$mail->AddCC(trim($cc));
}
}
}
if(count($attachmentArr) > 1)
{
$zipFileName = "Archieve-".uniqid().".zip";
if($this->create_zip($attachmentArr, $zipFileName, true)) {
$mail->AddAttachment($SavePath.$zipFileName); // attachment
sleep(20);
}
} else
{
foreach($attachmentArr as $attachment)
{
$mail->AddAttachment($SavePath.$attachment); // attachment
}
}
$msgbody = str_replace("<%EMAILSENTDATE%>", date('d/m/Y', strtotime($emailNamearr[$email]['serviced'])) , $body );
if(isset($emailNamearr[$email]))
{
$msgbody = str_replace("<%CLIENTNAME%>", "for ".$emailNamearr[$email]['company'] , $msgbody );
}
else $msgbody = str_replace("<%CLIENTNAME%>", "" , $msgbody );
$mail->MsgHTML($msgbody);
try
{
$mail->Send();
}catch(Exception $e)
{
echo "<br/><br/>$e<br/><br/>".$e;die;
}
//echo "$email <br/>";
$mail->ClearAddresses();
$mail->ClearAttachments();
$mail->ClearCCs();
} catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
$b = false;
}
}
}
After tearing out quite a bit of hair on my head I think I kind of sort out the issue. Here's what I did (in case anyone else is facing the same problem )
Under IIS->My Website->error pages->Edit Features Settings By default Detailed errors for local request is selected for security purposes.
This threw the 500 error but the actual cause was hidden. By changing it to "Detailed errors" the actual error was revealed which was :
"FastCGI process exceeded" I believe by default it's 30 secs.
So even though I've max_execution_limit = 300 the process was getting stopped/failed because of the php-cgi.exe 's execution time limit.
To solve this:
edit %windir%\system32\inetsrv\config\applicationHost.config file to extend the php-cgi.exe execution time limit. set activityTimeout:3600 and requestTimeout:3600 .. i set 3600 to be on safe side and because i could.
And then the application ran just fine.
Hope this helps saving the hair on head for someone.
I think:
Yii::app()->params['SMTPStatus'] is not 'enabled'
so phpmailer uses php native mail function witch, I think, is not configured in your php.ini
Hope this helps
$phpMailer = New PHPMailer();
$phpMailer->isSMTP();
$phpMailer->SMTPKeepAlive = true;
for ( ... ) {
// Send your emails right away
[ ... ]
}
$phpMailer->SmtpClose();
HI, I have an example code for KeepAlive SMTP here, but my problem is I send email with difference contents to my users. So each user have 1 content.
Can I do it like this:
for ( ... ) {
$phpMailer->addAddress($user['email'], $user['name']);
$phpMailer->Subject = $user['subject'];
$phpMailer->Body = $user['body'];
$phpMailer->Send()
}
Will the ->addAddress increase my recipients every time on the loop? Or will it clean the old recipient after ->send() comitted ?
Call clearAddresses() Before addAddress function . It is cleared before recipients.
$phpmailer->ClearAddresses();
$phpMailer->addAddress($user['email'], $user['name']);
I've written my own Code Igniter model for sending emails. All was fine until recently when I started to get this error:
Fatal error: Cannot redeclare class phpmailerException in /home/mysite/public_html/subdir/application/libraries/phpmailer/class.phpmailer.php on line 2319
I'm using:
CodeIgniter 2
PHPMailer 5.1
I've tried the following to resolve it:
Added "$mail->SMTPDebug = 0" to turn off errors.
Added: "$mail->MailerDebug = false;"
Modified the PHPMailer to only show errors when SMTPDebug is turned on.
Looked for and removed any echo statements
Added try / catch blocks Tried adding / removing: $mail = new PHPMailer(true);
Here is my controller method (company/contact) which calls my model (message_model):
function contact()
{
//Do settings.
$this->options->task='email';
$this->options->change = 'sent';
$this->options->form_validation='';
$this->options->page_title='Contact Us';
//Import library
include_once('application/libraries/recaptcha/recaptchalib.php');//Include recaptcha library.
//Keys for recaptcha, stored in mainconfig file.
$this->options->publickey = $this->config->item('recaptcha_public');
$this->options->privatekey = $this->config->item('recaptcha_private');
//Form validation
$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
$this->form_validation->set_rules('name_field','Name of problem','trim|required|min_length[3]|max_length[100]');
$this->form_validation->set_rules('desc_field','Description','trim|required|min_length[10]|max_length[2000]');
$this->form_validation->set_rules('email_field','Your email address','trim|required|valid_email');
$this->form_validation->set_rules('recaptcha_response_field','captcha field','trim|required|callback__check_recaptcha');
//If valid.
if( $this->form_validation->run() )
{
//Set email contents.
$message="This is a message from the contact form on ".$this->config->item('site_name')."<br /><br />";
$message.=convert_nl($this->input->post('desc_field'));
$message.="<br /><br />Reply to this person by clicking this link: ".$this->input->post('name_field')."<br /><br />";
$options = array('host'=>$this->config->item('email_host'),//mail.fixilink.com
'username'=>$this->config->item('email_username'),
'password'=>$this->config->item('email_password'),
'from_name'=>$this->input->post('name_field'),
'to'=>array($this->config->item('email_to')=>$this->config->item('email_to') ),
'cc'=>$this->config->item('email_cc'),
'full_name'=>$this->input->post('name_field'),
'subject'=>'Email from '.$this->config->item('site_name').' visitor: '.$this->input->post('name_field'),
'message'=>$message,
'word_wrap'=>50,
'format'=>$this->config->item('email_format'),
'phpmailer_folder'=>$this->config->item('phpmailer_folder')
);
//Send email using own email class and phpmailer.
$result = $this->message_model->send_email($options);
//Second email to sender
//Set email contents.
$message="Thank you for your enquiry, we aim to get a reply to you within 2 working days. In the meantime, please do follow us on www.facebook.com/autismworksuk";
$options = array('host'=>$this->config->item('email_host'),//mail.fixilink.com
'username'=>$this->config->item('email_username'),
'password'=>$this->config->item('email_password'),
'from_name'=>$this->input->post('name_field'),
'to'=>$this->input->post('email_field'),
'full_name'=>$this->input->post('name_field'),
'subject'=>'Email from '.$this->config->item('site_name'),
'message'=>$message,
'word_wrap'=>50,
'format'=>$this->config->item('email_format'),
'phpmailer_folder'=>$this->config->item('phpmailer_folder')
);
//Send email using own email class and phpmailer.
$result = $this->message_model->send_email($options);
//Set result.
if($result==-1)
$this->session->set_flashdata('result', ucfirst($this->options->task).' was not '.$this->options->change.' because of a database error.');
elseif($result==0)
$this->session->set_flashdata('result', 'No changes were made.');
else
$this->session->set_flashdata('result', ucfirst($this->options->task).' was '.$this->options->change.' successfully.');
//Redirect to completed controller.
redirect('completed');
}
//Validation failed or first time through loop.
$this->load->view('company/contact_view.php',$this->options);
}
Here is my model's method to send the emails. It used to work but without any changes I can think of now I get an exception error:
function send_email($options=array())
{
if(!$this->_required(array('host','username','password','from_name','to','full_name','subject','message'),$options))//check the required options of email and pass aggainst provided $options.
return false;
$options = $this->_default(array('word_wrap'=>50,'format'=>'html','charset'=>'utf-8'),$options);
try
{
if(isset($options['phpmailer_folder']))
require($options['phpmailer_folder']."/class.phpmailer.php");
else
require("application/libraries/phpmailer/class.phpmailer.php");//Typical CI 2.1 folder.
$mail = new PHPMailer();
$mail->MailerDebug = false;
//Set main fields.
$mail->SetLanguage("en", 'phpmailer/language/');
$mail->IsSMTP();// set mailer to use SMTP
$mail->SMTPDebug = 0;
$mail->Host = $options['host'];
$mail->SMTPAuth = TRUE; // turn on SMTP authentication
$mail->Username = $options['username'];
$mail->Password = $options['password'];
$mail->FromName = $options['from_name'];//WHo is the email from.
$mail->WordWrap = $options['word_wrap'];// Set word wrap to 50 characters default.
$mail->Subject = $options['subject'];
$mail->Body = $options['message'];
$mail->CharSet = $options['charset'];
//From is the username on the server, not sender email.
if(isset($options['from']))
$mail->From = $options['from'];
else
$mail->From = $mail->Username; //Default From email same as smtp user
//Add reply to.
if(isset($options['reply_to']))
$mail->AddReplyTo($options['reply_to'], $options['from']);
if(isset($options['sender']))
$mail->Sender = $options['sender'];
//Add recipients / to field (required)
if(is_array($options['to']))
{
foreach($options['to'] as $to =>$fn)
$mail->AddAddress($to, $fn);
}
else
{
$mail->AddAddress($options['to']); //Email address where you wish to receive/collect those emails.
}
//Add cc to list if exists. Must be an array
if(isset($options['cc']))
{
if(is_array($options['cc']))
{
foreach($options['cc'] as $to =>$fn)
$mail->AddCC($to, $fn);
}
else
{
log_message('debug', '---->CC field must be an array for use with Message_Model.');
}
}
//Add bcc to list if exists. Must be an array
if(isset($options['bcc']))
{
if(is_array($options['bcc']))
{
foreach($options['bcc'] as $to =>$fn)
$mail->AddBCC($to, $fn);
}
else
{
log_message('debug', '---->BCC field must be an array for use with Message_Model.');
}
}
//Alternative text-only body.
if(isset($options['alt_body']))
$mail->AltBody=$options['alt_body'];
else
$mail->AltBody = htmlspecialchars_decode( strip_tags( $options['message'] ),ENT_QUOTES );//Strip out all html and other chars and convert to plain text.
//Plain/html format.
if(isset($options['format']))
{
if($options['format']=='html')
$mail->IsHTML(true); // set email format to HTML
}
//Send email and set result.
$return['message']='';
if(!$mail->Send())
{
$return['message'].= "Message could not be sent.<br />\n";
$return['message'].= "Mailer Error: " . $mail->ErrorInfo."\n";
$return['result'] = 0;
}
else
{
$return['message'].= "Message has been sent successfully.\n";
$return['result'] = 1;
}
}
catch (phpmailerException $e)
{
log_message('error', '---->PHPMailer error: '.$e->errorMessage() );
}
catch (Exception $e)
{
log_message('error', '---->PHPMailer error: '.$e->errorMessage() );
}
return $return;
}
if (!class_exists("phpmailer")) {
require_once('PHPMailer_5.2.2/class.phpmailer.php');
}
This Code will clear this issue 100%..
Basically one of two things is happening:
You are "including" your PHP code twice somewhere, causing the 2nd time to generate the redeclaration error
You are using "phpmailerException" somewhere else, besides your model. Have you tried to do a "find all" in your IDE for ALL calls to "phpmailerException" - perhaps you used this name in another area for another exception?
require_once("class.phpmailer.php") is better.
Mukesh is right that require_once will solve Sift Exchanges answer #1. However, there is not need to check if the class exists as require_once does that.