phpmailer stops suddenly in case of big attachments - php

Problem
I have a script to send newsletters to my contacts. The script works fine, if I have no attachement (proven with 2,000 emails).
Now, if I use attachments, the script works fine too. But only by sending about 30 emails.
Test-Setup
group of 100 emails to be performed (loop).
attachments: 2 files (total 4,6 MB) --> the script terminates (but without error message) after 50 seconds and 34 emails sent. (~ 156 MB).
Test-Variations
changing in php.ini memory_limit from 100M to 500M --> has no effect. Still error after 34 emails.
putting a sleep(5) after each loop --> has no effect. Still error after 34 emails.
no attachments: all 100 emails are sent (about 30 seconds).
no attachements on 2000 emails: all 2000 emails are sent (about 6 minutes).
no effect of changing max_execution_time in php.ini.
Assumtions
Due to the behaviour I expect to have a memory-problem and not a time-problem.
But a test of the memory (memory_get_usage()) in each loop showed that the memory of the first loop is 1.1 MBand of the 34th loop 1.2 MB.
Question
Please find below my code, but I guess it sould be ok.
Does anybody has an idea what is causing the issue? Many thanks!
myMailer.class
class myMailer extends PHPMailer {
public function __construct(?bool $exceptions = true) {
$config = parse_ini_file('../../ini/config.ini', true);
parent::__construct($exceptions);
try {
// Language of Errors
$this->setLanguage('en', dirname(__FILE__) . '/../external/PHPMailer/language/');
// Server settings
$this->SMTPDebug = 0; // Enable verbose debug output
$this->isSMTP(); // Set mailer to use SMTP
$this->SMTPAuth = true; // Enable SMTP authentication
$this->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$this->Port = 465; // TCP port to connect to
$this->Host = $config['smtp_server']['host']; // SMTP server
$this->Username = $config['smtp_server']['username']; // SMTP username
$this->Password = $config['smtp_server']['password']; // SMTP password
$this->CharSet ='UTF-8'; // Set Character Set
$this->isHTML(true); // Set email format to HTML
$this->setFrom("office#superman.com", "superman OFFICE");
} catch (Exception $e) {
// echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
trigger_error("myMailer(): " . $this->ErrorInfo,E_USER_ERROR);
}
}
public function setBody(string $salutation, string $receiver, string $message) : void {
// Linebreak to <BR>
$message = nl2br($message);
// Create Body
$body = file_get_contents('../../ini/email_template.html');
$body = str_replace("{Receiver}", $receiver, $body);
$body = str_replace("{Salutation}", $salutation, $body);
$body = str_replace("{Message}", $message, $body);
$this->Body = $body;
}
}
send_emails.php
<?php
$groupID = $_POST['id'];
$subject = $_POST['Subject'];
$message = $_POST['Message'];
$attachments = (key_exists('Files', $_POST)) ? $_POST['Files'] : array();
$group = new Group($groupID);
// Prepare and get HTML
$htmlGenerator = HtmlGenerator::getInstance();
$htmlGenerator->setTitle("sending emails");
$header = $htmlGenerator->getWebbaseHtmlHeader();
$footer = $htmlGenerator->getWebbaseHtmlFooter();
echo $header;
?>
<div class="container">
<h1>Emailing</h1>
<h3>Group: <?php echo $group->getTitle(); ?></h3>
<h4>Number of members: <?php echo $group->getNumberOfMembers(); ?></h4>
<?php
$strScreenOutput = "
<table class='table table-sm table-hover table-responsive-md'>
<thead class='thead-dark'>
<th scope='col'>Nr.</th>
<th scope='col'>Date</th>
<th scope='col'>Company</th>
<th scope='col'>Lastname</th>
<th scope='col'>Firstname</th>
<th scope='col'>Email</th>
<th scope='col'>Newsletter</th>
<th scope='col'>Result</th>
</thead>
<tbody>";
$protocol = $strScreenOutput;
echo $strScreenOutput;
$i = 0;
$members = Contact::getAllOfGroup($groupID);
foreach ($members as $contact) {
$i++;
$datRun = date('d.m.Y (H:i:s)');
if ($contact->getNewsletter() === false) {
$result = "no sub.";
} elseif ($contact->getEmail() === "" || $contact->getEmail() === null) {
$result = "no email";
} else {
$return = $contact->sendEmail($subject, $message, $attachments);
$result = ($return===true) ? "ok" : $return;
}
// create feedback for browser
$strScreenOutput = "<tr>";
$strScreenOutput .= "<th scope='row'>".str_pad($i, 4 ,'0', STR_PAD_LEFT)."</th>";
$strScreenOutput .= "<td>{$datRun}</td>";
$strScreenOutput .= "<td>{$contact->getCompany()}</td>";
$strScreenOutput .= "<td>{$contact->getLastName()}</td>";
$strScreenOutput .= "<td>{$contact->getFirstName()}</td>";
$strScreenOutput .= "<td>{$contact->getEmail()}</td>";
$strScreenOutput .= "<td>".(($contact->getNewsletter()) ? "yes" : "no")."</td>";
$strScreenOutput .= "<td>{$result}</td>";
$strScreenOutput .= "</tr>";
echo str_pad($strScreenOutput,4096)."\n"; // Add some additional blanks to enable flushing (as some browsers suppress flushing)
// create internal protocol
$protocol .= $strScreenOutput . "\n";
// Send to browser
flush();
ob_flush();
// add some execution time
set_time_limit(30);
}
$strScreenOutput = "</tbody>
</table>";
$protocol .= $strScreenOutput;
echo $strScreenOutput;
?>
<h3>Emails successfully transmitted.</h3>
</div>
<?php
// send protocols
$protocol = "<h3>Group: {$group->getTitle()}</h3>".$protocol;
$protocol = "<div style='margin-top: 30px'>$protocol</div>";
$internal = new Contact(1);
$internal->sendEmail("PROTOCOL: ".$subject, $message . $protocol, $attachments);
echo $footer;
Contact::sendEmail()
public function sendEmail(string $subject, string $message, array $attachments = array()) {
$mail = new myMailer();
if ( is_null($this->getEmail() || $this->getEmail() == "") ) {
return false;
} else {
try {
// Compose Email
$mail->addAddress($this->getEmail(), $this->getFirstName() . " " . $this->getLastName());
$mail->Subject = $subject;
$mail->setBody($this->getSalutationText(), $this->getAddress(), $message);
foreach ($attachments as $file) {
$uploadPath = $_SERVER['DOCUMENT_ROOT'] . "/../../files/email_attachments/";
$file_url = $uploadPath.$file;
if (! is_dir($uploadPath)) { die("Folder \"$uploadPath\" does not exist.");}
if (! file_exists($file_url)) { die("File \"$file_url\" does not exist."); }
$mail->addAttachment($file_url);
}
$return = $mail->send();
// clean up
$mail->clearAddresses();
$mail->clearAttachments();
} catch (Exception $error) {
$return = $error->getMessage();
}
return $return;
}
unset($mail);
}

It does sound like a memory problem - PHPMailer isn't very efficient on memory when sending large attachments - try echoing what you get from memory_get_usage() inside your loop to confirm memory consumption.
Generally though, you're sending quite inefficiently because you're creating a new PHPMailer instance, reprocessing the same attachments, and opening a new SMTP connection for every message, all of which only need doing once. For how to send more efficiently, look at the mailing list example provided with PHPMailer, and the wiki doc on sending to lists.
A more efficient reuse of instance and connection may reduce your overall memory requirements.

Related

How to get new emails on the first try with imap_open in php

I have a PHP script which opens an email inbox, searches for the last email and then performs some other operations if this email has the UNSEEN header.
The script is run by a cron job, and it works fine. The problem is that sometimes it takes several attempts before actually finding the new email, even if the email has already arrived.
If someone sees i'm missing something, or knows how to ensure i get all emails on the first try, please let me know. This is the relevant email opening and searching code code:
//open mailbox
$inbox = imap_open('{<domain>/imap/ssl/novalidate-cert}INBOX', '<email-address>', '<password>');
$newEmails = false;
// grab a list of all the mail headers
$msgnos = imap_search($inbox, 'ALL');
$headers = imap_headers($inbox);
$last = imap_num_msg($inbox);
//check if the last email is marked as unread (U means unread)
$headerinfo = imap_headerinfo($inbox, $last);
if($headerinfo->Unseen == 'U') {
$newEmails = true;
file_put_contents("program_logs.txt","[".date('d-m-Y H:i') . "] program executed. New mails found. \r\n",FILE_APPEND);
}
echo $headerinfo->Unseen . "<br>";
//read email if the last email is unread
if($newEmails == true){
$header = imap_header($inbox, $last);
$body = imap_fetchbody($inbox, $last,1);
$structure = imap_fetchstructure($inbox, $last);
$boxname = $header->from[0]->mailbox;
$hostname = $header->from[0]->host;
$title = $header->subject;
$from = $boxname."#".$hostname;
echo "<h2>Body structure Encoding:</h2>";
var_dump($structure->encoding);
echo "<hr>";
if($structure->encoding == 3){
$body = base64_decode($body);
}
if($structure->encoding == 4){
$body=quoted_printable_decode($body);
}
echo "<h2>Is body html?</h2>";
if($body != strip_tags($body)){
echo "body is html.<br>";
$body = preg_replace( "/\n\s+/", "\n", rtrim(html_entity_decode(strip_tags($body))) );
echo "converted to plain text.";
}else{
echo "body is not html";
}
echo "<hr>";
echo "<h2>From:</h2>".$from;
echo "<hr>";
echo "<h2>Body:</h2>".$body;
echo "<hr>";
echo "<h2>title:</h2>".$title;
echo "<hr>";
file_put_contents("program_logs.txt","Email is from ".$from. " \r\n",FILE_APPEND);
}else{
echo 'No new notifications';
echo "<hr>";
echo "<h2>imap erros:</h2>";
var_dump(imap_errors());
imap_close($inbox);
echo '<hr>';
file_put_contents("program_logs.txt","[".date('d-m-Y H:i') . "] program executed, no new mails found. \r\n",FILE_APPEND);
}

MimeMailParser Extension IMAP Setup

Currently I have an old script that parses emails, as seen here:
// Accessing the mailbox
$mailbox = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX", $mailbox, $mailboxPassword);
// Retrieving only unread messages
$mail = imap_search($mailbox, 'UNSEEN');
// If no new messages found aborting the script
if(empty($mail)) die('No unread emails found!');
$total_found = 0;
$skipped = 0;
// Now we loop through messages
foreach ($mail as $key => $val) {
// process everything
}
This works fine other than some encoding issues with Russian (Cyrillic) characters and a few other issues. While I could hunt down all these issues individually, it seems like there are already great mail parsing classes out there. I found this, which I'd like to use as it sounds like this gets suggested often.
The example code provided is with the parser is below.
<?php
require_once('MimeMailParser.class.php');
$path = 'path/to/mail.txt';
$Parser = new MimeMailParser();
$Parser->setPath($path);
$to = $Parser->getHeader('to');
$from = $Parser->getHeader('from');
$subject = $Parser->getHeader('subject');
$text = $Parser->getMessageBody('text');
$html = $Parser->getMessageBody('html');
$attachments = $Parser->getAttachments();
?>
However it seems to need a reference to $path which is confusing me as the emails are not stored in a folder, there pulled from IMAP. Would I add $path = $mail; in the foreach block? If not, what format do I supply the email to the parser in? Do I have to use the same script I already have and save it to a folder?
All the emails are being retrieved from Gmail. I used IMAP but could use POP instead if IMAP wont work.
Based on the suggested answer i tried this code but its just looping through x unread emails and displaying blank data for everything, headers and body?
// Accessing the mailbox
$mailbox = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX", $mailbox, $mailboxPassword);
// Retrieving only unread messages
$mail = imap_search($mailbox, 'UNSEEN');
// If no new messages found aborting the script
if(empty($mail)) die('No unread emails found!');
$total_found = 0;
$skipped = 0;
// Now we loop through messages
foreach ($mail as $email) {
$Parser = new MimeMailParser();
$Parser->setText($mail);
echo "-----------------------------Start Of Email---------------------------------";
echo "<br /><br /><br /><br />";
$to = $Parser->getHeader('to');
echo "To: " . $to . "<br />";
$from = $Parser->getHeader('from');
echo "From: " . $from . "<br />";
$subject = $Parser->getHeader('subject');
echo "Subject: " . $subject . "<br /><br /><br />";
//$text = $Parser->getMessageBody('text');
$html = $Parser->getMessageBody('html');
echo "Body: " . "<br /><br />" . $html . "<br />";
//$attachments = $Parser->getAttachments();
echo "<br /><br /><br /><br />";
echo "-----------------------------End Of Email---------------------------------";
}
That class has another function to set the message content directly. Just call $Parser->setText($mail) where $mail is the message content in your IMAP foreach loop.

PHPmailer - Multiple sending of e-mail

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.

imap_search() for unseen messages does not returning anything

I am currently trying to get the UNSEEN/UNREAD messages from my server. Currently, I have this:
$openmail = imap_open($dns, $email, $password) or die("Cannot Connect " . imap_last_error());
if ($openmail) {
/* grab emails */
$emails = imap_search($openmail, 'UNSEEN');
if ($emails) {
//For every e-mail.
$tot = imap_num_msg($openmail);
for ($i = $tot; $i > 0; $i--) {
$structure = imap_fetchstructure($openmail, $i);
if (isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) {
$part = $structure->parts[1];
$message = imap_fetchbody($openmail, $i, 2, FT_PEEK);
if ($part->encoding == 3) {
$message = imap_base64($message);
} else if ($part->encoding == 1) {
$message = imap_8bit($message);
} else {
$message = imap_qprint($message);
}
}
$header = imap_header($openmail, $i);
$from = imap_utf8($header->fromaddress);
$subject = $header->Subject;
$subject = substr($subject, 0, 150);
$date = $header->Date;
}
/* Print out the Unseen messages in here! */
} else {
/* No unseen messages */
echo "No unseen";
}
}
I've tried sending multiply emails to my mailserver, refreshed the page with the above script. But I keep getting the "No unseen".
I've tried to output the $emails but it's empty. It can't find anything.
If I try to just get ALL the messages (no unseen filter), I can see the emails I've sent to the mailbox, although, they're all marked as read.
Your code $message = imap_fetchbody($openmail, $i, 2, FT_PEEK); uses hardcoded part offsets, i.e. it assumes that a message is always multipart/alternative with text/plain and text/html. That's a very wrong assumption.
You have to look at the output of the BODYSTRUCTURE to see what the MIME structure of your mail is.
With that out of the way, be sure that none of your commands use the BODY fetch operation; you have to use BODY.PEEK. I have no idea how this is accessible within the PHP c-client bindings.

phpmailer error Could not instantiate mail function on WINDOWS server

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

Categories