Hi,
I have built and implemented a simple emailer script to send out emails
using fgets fput etc.
First I have a cron job build an email queue table
then a different cron job to check the queue and send out emails.
If the emails fail then they stay on the queue for 6 attempts.
At present it opens a new socket each time it sends an email
which must be slowing it down.
I would like to adjust my script so that it opens the socket and
then sends maybe 50 emails in one go, then closes the socket,
pauses some seconds, then opens a another sock and sends again.
BUT - I'm not sure how to adjust my script. :o
This is what I have:
First my send-mail function:
<?php
/*
* send_email_func.php
*
*
*/
function send_email_fnc($fromname, $reply_cd, $to, $toname, $subject, $message) {
//SMTP + SERVER DETAILS
/* * * * CONFIGURATION START * * * */
$smtpServer = "mail.example.net";
$port = "25";
$timeout = "2";
$username = "myuser";
$password = "my-password";
$from = "admin@example.net";
$reply_ad = $reply_cd."@example.net";
$identify = "localhost"; // Used at the start of the connection to identify yourself but value isn't checked
$newLine = "\r\n";
/* * * * CONFIGURATION END * * * * */
//Connect to the host on the specified port
$smtpConnect = @fsockopen($smtpServer, $port, $errno, $errstr, $timeout);
if(empty($smtpConnect)) {
$logArray['errno'] = $errno;
$logArray['errstr'] = $errstr;
$logArray['connection'] = "Failed to connect";
$logArray['SUCCESS'] = "FALSE";
return $logArray;
}
stream_set_timeout($smtpConnect, $timeout);
$smtpResponse = fgets($smtpConnect, 515);
$info = stream_get_meta_data($smtpConnect);
if ($info['timed_out']) {
$logArray['connection'] = "Timeout: $smtpResponse";
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
$logArray['connection'] = "Connected: $smtpResponse";
//--- Say hello to the server --------
fputs($smtpConnect,"EHLO ".$identify . $newLine);
$logArray['ehlo'] = fgets($smtpConnect, 515);
$info = stream_get_meta_data($smtpConnect);
$i=0;
while (!$info['timed_out']) {
$logArray['ehlo'] .= fgets($smtpConnect, 515);
$info = stream_get_meta_data($smtpConnect);
$i++;
}
if ($i=0) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- Request Auth Login --------
fputs($smtpConnect,"AUTH LOGIN" . $newLine);
$logArray['authrequest'] = fgets($smtpConnect, 515);
if (false === strpos($logArray['authrequest'],"334")) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- Send username --------
fputs($smtpConnect, base64_encode($username) . $newLine);
$logArray['authusername'] = fgets($smtpConnect, 515);
if (false === strpos($logArray['authusername'],"334")) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- Send password --------
fputs($smtpConnect, base64_encode($password) . $newLine);
$logArray['authpassword'] = fgets($smtpConnect, 515);
if (false === strpos($logArray['authpassword'],"235")) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- Email From --------
fputs($smtpConnect, "MAIL FROM: $from" . $newLine);
$logArray['mailfrom'] = fgets($smtpConnect, 515);
if (false === strpos($logArray['mailfrom'],"250")) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- Email To --------
fputs($smtpConnect, "RCPT TO: $to" . $newLine);
$logArray['mailto'] = fgets($smtpConnect, 515);
if (false === strpos($logArray['mailto'],"250")) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- The Email --------
fputs($smtpConnect, "DATA" . $newLine);
$logArray['data1'] = fgets($smtpConnect, 515);
if (false === strpos($logArray['data1'],"354")) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- Construct Headers --------
$headers = "MIME-Version: 1.0" . $newLine;
$headers .= "Content-type: text/html; charset=iso-8859-1" . $newLine;
$headers .= "To: ".$toname." <".$to.">". $newLine;
$headers .= "From: ".$fromname." <".$from.">" . $newLine;
$headers .= "Subject: ".$subject.$newLine;
$headers .= "Reply-To: ".$reply_ad.$newLine;
$message = str_replace("\n.", "\n..",$message);
fputs($smtpConnect, $headers.$newLine.$message."\n.\n");
$logArray['data2'] = fgets($smtpConnect, 515);
if (false === strpos($logArray['data2'],"250")) {
$logArray['SUCCESS'] = "FALSE";
fclose($smtpConnect);
return $logArray;
}
//--- Say Bye to SMTP --------
fputs($smtpConnect,"QUIT" . $newLine);
$logArray['quit'] = fgets($smtpConnect, 515);
//fclose($smtpConnect);
$logArray['SUCCESS'] = "TRUE";
return $logArray;
}
Now the calling script which also updates my tables and writes a log.
<?php
/*
* send_queue.php
*
* Sending Queued Messages
*/
require_once("my_functions.php");
require_once("bbcode_email.php");
require_once("send_email_func.php");
function write_log($content) {
global $handle;
$content = $content."\r\n";
fwrite($handle, $content);
} // End of Function
function write_error($content) {
global $handle;
fwrite($handle, $content);
exit;
} // End of Function
$re1 = array("/\n/",
"/\s{2,}/",
"/>\s+</",
"/<br.*>/",
"/<[^>]+>/");
$re2 = array(" ",
" ",
" ",
" \n",
"");
function wrap_it($str,$max){
$str = explode(" ", $str );
$out = "";
$line = "";
foreach($str as $wrd){
if(strlen($line." ".$wrd) < $max){
$s = " ";
}
else {
$s = "<br>";
}
if( $s===" " ) {
$line = $line.$s.$wrd;
}
else {
$line = $wrd;
}
$out .= $s.$wrd;
} // end foreach
return $out;
} // end function
$log_file = "/home/exp526d/public_html/a_log_SEND.txt";
$handle = fopen("$log_file", "a");
//$today = $today-10800;
$stamp = date('H:i:s l, j F Y', $today);
write_log("----------------------------------------------- \r\nNew record - Time Stamp: $stamp ");
write_log("This script: send_queue.php, This file: $log_file");
echo "<br>This file: $log_file<br>";
$sql = "SELECT * FROM emailqueue WHERE sent = 'n' AND attempts < 5 ";
$result = mysql_query($sql) or write_error("Could not do emailqueue Query 1 ".mysql_error()." \r\n");
$num = mysql_num_rows($result);
if ($num == 0 ) {
write_log("No Valid Emails in Queue");
exit;
} // end if
while($row = mysql_fetch_assoc($result)){
extract($row);
$content = wordwrap($mess, 70, "\n");
$content = nl2br($content);
$content = str_replace("<br />", "<br>", $content);
$content = eml_bbcode($content,$contact);
$message_html = $content."<br><br>
<b>This is an opt-in only e-course.</b><br>
If you wish to cancel this at any time,<br>
please click here: <a href=\"http://www.expressresponse.net/unsubscribe.php?a=$sub_no\">E-course Cancellation.</a>
<br><br>
<br><br>
Published for $fm_name, By ExpressResponse.Net Waterfront Drive, Road Town. British Virgin Islands. <br>
© 2012 $fm_name All rights reserved.";
$message_text = "text";
$message_text = preg_replace($re1,$re2,$message_html);
$reply_cd = "sub_".$sub_no;
write_log("Processing Email: $queue_id to: $to_mail\n");
$logArray = send_email_fnc($fm_name, $reply_cd, $to_mail, $contact, $subject, $message_html);
if ( $logArray['SUCCESS'] === "TRUE" ) {
$sql = "UPDATE emailqueue SET
sent = 'y',
attempts = attempts+1,
sent_date = '$today_time'
WHERE queue_id = '$queue_id' ";
mysql_query($sql) or write_error("UPDATE emailqueue query problem1".mysql_error()." \r\n");
write_log("Successfully Sent: $queue_id to: $to_mail\n");
} // end if
else {
$sql = "UPDATE emailqueue SET
sent = 'n',
attempts = attempts+1
WHERE queue_id = '$queue_id' ";
mysql_query($sql) or write_error("Email Fail query problem".mysql_error()." \r\n");
$sql = "INSERT INTO `email_fail` (type,queue_no,client_no,camp_no,sub_no,mess_no,to,send_dt,connection,helo,authrequest,authusername,authpassword,mailfrom,mailto,data1,data2,quit,errno,errstr) VALUES ( '$send_type','$to','$today_time',$logArray[connection],$logArray[ehlo],$logArray[authrequest],$logArray[authusername],$logArray[authpassword],$logArray[mailfrom],$logArray[mailto],$logArray[data1],$logArray[data2],$logArray[quit],$logArray[errno],$logArray[errstr])";
mysql_query($sql) or write_error("Email Fail query problem2".mysql_error()." \r\n");
write_log("Sent Failed: $queue_id to: $to_mail\r\n");
} // end else
} // end while
fclose($handle);
?>
Can you see how I can change this so that I can sent out batches of 50 from
my queue ?
Once I an happy the script is running well, I will probably stop the logging as this no doubt slows it down a lot.
Do you think the table update should also be written as a batch of 50 as well ?
Might be a bit difficult to write that ? 😕
Thanks for any help.
[PS I respect every ones point of view, but please don't suggest
I use this mailer class or that class,
the reason for having my own script is so that I can understand
exactly what is happening and can adjust it as nec.
( actually I am very poor at getting my head round OOP so I just stick with
procedural php. ( for now anyway ) ]
.