1

I need to send a few hundred emails at a time to registered users and I'm running into a problem. The PHP script I use (and have used before with no issues on a different hosting service) lags the entire server (which has 8GB RAM by the way) for as long as it is sending emails.

Now, I talked to the hosting support people, asking if something's wrong with their mail server, or if there are some outgoing mail limitations or whatever, and they said no. In fact, they are adamantly claiming that it's a coding issue. I highly doubt that, but it's possible the script was slightly altered since its last use a few months back, so I'm sharing the script below, and a typical email I would be sending is in the $content variable.

The question is, can someone see a reason why this code would eat up resources like crazy?

I have checked the MySQL logs, and the query itself (which gets emails from the database) isn't slow. So it's the mailing itself.

PHP mail_sender file:

$content="<p style='line-height:20px;margin:10px 0;'>Hello,</p>

<p style='line-height:20px;margin:10px 0;'>This is an email to notify you etc etc.</p>

<p style='line-height:20px;margin:10px 0;'>This is line 2 of the email, it's usually not much longer than this example.</p>

<p style='line-height:20px;margin:10px 0;'>Regards,<br/>Site Name staff</p>";

$result=mysql_query("select email from members where tipster_by_email='1' ") or die(mysql_error());
while($row=mysql_fetch_assoc($result)){
    sendToUser($row['email'],$admin_email,"Email Title",$content);
}

And this is the function itself:

//generic HTML-formatted e-mail sender
function sendToUser($email,$admin_email,$subject,$content){

//define the receiver of the email
$to = $email;
//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));
//define the headers we want passed. Note that they are separated with \r\n
$headers="From: Site Name <$admin_email>";
$headers.="\r\nReply-To: $admin_email";
//add boundary string and mime type specification
$headers .= "\r\nMIME-Version: 1.0"; 
$headers .= "\r\nContent-Type: text/html; ";
//define the body of the message.
ob_start(); //Turn on output buffering 
?>

<div style="width:730px;text-align:justify;margin-bottom:25px;">

<?php echo stripslashes($content); ?>

<div style='width:100%;height:1px;background:#ccc;margin:10px 0;'></div>

<div style='width:100%;color:#333;font-size:12px;'>
    <p style='line-height:12px;margin-top:10px;'>Site Name is owned by Company Name</p>
    <p style='line-height:12px;margin-top:10px;'>All rights reserved.</p>
    <p style='line-height:12px;margin-top:10px;'><a style='color:blue;' href='facebookurl'>Like us on Facebook</a> or <a style='color:#b04141;' href='twitterurl'>follow us on Twitter</a></p>
</div>

</div>

<?php
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();
//send the email
mail( $to, $subject, $message, $headers );
}

Is there any reason whatsoever for this to use up resources or have a slow execution? The server is very fast and doesn't have a problem with anything else.

Mail settings in php.ini:

Mail    SMTP    Used under Windows only: host name or IP address of the SMTP server PHP should use for mail sent with the mail() function.  [strikethrough]localhost[/strikethrough] **DEFAULT**, Click to Edit
Mail    sendmail_from       [strikethrough][email protected][/strikethrough] **DEFAULT**, Click to Edit
Mail    sendmail_path       /usr/sbin/sendmail -t -i
Mail    smtp_port       25
9
  • 1
    Are you sending the same content to every user? If so, you can simply send one email out, and add every user as a BCC address.
    – andrewsi
    Commented Aug 7, 2013 at 18:08
  • Sometimes, yes. But often there's an "unsubscribe" link in line 2 of the email, which is unique to every user, so I can't do that. But thanks for the idea, I didn't know that. Commented Aug 7, 2013 at 18:09
  • How many records does this query return? : select email from members where tipster_by_email='1' Commented Aug 7, 2013 at 18:12
  • A few hundred. But the script lags the entire server for like 20 seconds even if I limit the query to 50 results. Commented Aug 7, 2013 at 18:14
  • What are the mail settings in your php.ini file? Commented Aug 7, 2013 at 18:49

1 Answer 1

0

@Pitchinnate mentioned that ob_*() functions aren't the best performing. I can't definitively comment one way or another on that, but it sounds plausible. A better option would be replacing:

ob_start(); //Turn on output buffering 
?>

<!-- HTML -->

<?php
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();

With:

$message = <<<_EOI_

<!-- HTML -->

_EOI_;

This is called 'HEREDOC' syntax and you can use $variables it in just like a double-quoted string.

Aside from that I can't really see anything that would cause problems for the MTA on the server. If you remove the output buffering bit and the script still causes problems with a few hundred messages I would have to say that the mail server configuration is not optimal. eg. They allow too many sendmail daemons to fire up in the background and it's eating away at the server memory.

Also, in all automated mailings you should always include some sort of unsubscribe mechanism whether it's a link or some instructions on how to opt out. That, and make sure that it works in a timely fashion. :P

1
  • I have an unsubscribe mechanism, I just didn't show it here because the lag is the same with or without it:) I'll try it without the ob part but I think it's just a matter of hosting support people dumping their job on me. Commented Aug 8, 2013 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.