SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Enthusiast
    Join Date
    Dec 2004
    Location
    uk
    Posts
    41
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Newsletter Script Help: How to send 2000+ emails safely?

    Hi all,

    I'm a newbie to PHP and it's a lot to take in but I'm really enjoying it so far. It opens up so many possibilities compared to a html only site. I have managed to put together a simple email script which is tested and working. The thing is, I'm currently using my test table which has 3 email addresses in it. The real table has over 2000 members. I've never emailed them in one go before but when I do, I want to make sure the script is going to work! The last thing I want is for it to crash or time out and some members get one email, some get two and some don't get anything. I have read that I may have a problem with using mail() for large lists.

    Should I modify my current script? If so, in what way? I'm really dumb at PHP at the moment so please be gentle. Any help would be much appreciated!

    Current Script
    Code:
    <?php
    include("../../opendb.php");
    mysql_select_db($dbname1);
     
    $mailtable = $_POST['table'];
    $mailsubject = $_POST['subject'];
    $mailmessage = stripslashes($_POST['message']);
     
    $sql="SELECT * FROM $table";
    $result=mysql_query($sql);
    while($rows=mysql_fetch_array($result)){
    $name = $rows['name'];
    $to = $rows['email'];
    $subject = "$mailsubject";
    $header = "from: Me <me@domain.com>";
    $message = "Dear $name \r\n";
    $message.= " \r\n";
    $message.= "$mailmessage \r\n";
    $message.=" \r\n";
    $message.="Warmest Regards \r\n";
    $message.="Me \r\n";
    $sentmail=mail($to,$subject,$message,$header);
    }
    if($sentmail){
    header("location:http://www.domain.com/success.html");
    }
    else {
    header("location:http://www.domain.com/failure.html");
    }
    include("../../closedb.php");
    ?>

  2. #2
    Use The Cloud
    Join Date
    Jan 2006
    Location
    Boise, ID
    Posts
    556
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The first thing I notice is you're checking for a valid mail return boolean outside of your while loop. If your while completes successfully, then $sentmail will only contain the bool value of the very last message sent, probably not intended.
    Brad Hanson, Web Applications & Scalability Specialist
    ► Is your website outgrowing its current hosting solution?
    ► PM me for a FREE scalability consult!
    ► USA Based: Available by Phone, Skype, AIM, and E-mail.

  3. #3
    SitePoint Enthusiast
    Join Date
    Dec 2004
    Location
    uk
    Posts
    41
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bhanson View Post
    The first thing I notice is you're checking for a valid mail return boolean outside of your while loop. If your while completes successfully, then $sentmail will only contain the bool value of the very last message sent, probably not intended.
    Thanks for the reply.

    Do you mean I should do something like the following to validate more effectively..?
    Code:
    $sentmail=mail($to,$subject,$message,$header);
    print("$to</br>");
    }
    ?>
    Just for the record, I'm not a spammer, the people I'm emailing know my website. Is my code so bad no one can face getting involved lol. Please help if you can. Even if it's to tell me my script is carp and I should stick with html hehe.

    If I wanted to mail in batches, what would I need to do? Say for example I wanted to take 100 at a time, what would I need to change in my code? Thanks for any help guys.

  4. #4
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you're sending out 2000+ emails, you should probably look at using a more powerful mailing library. I like swift: http://www.swiftmailer.org/
    MySQL v5.1.58
    PHP v5.3.6

  5. #5
    SitePoint Enthusiast
    Join Date
    Dec 2004
    Location
    uk
    Posts
    41
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BrandonK View Post
    If you're sending out 2000+ emails, you should probably look at using a more powerful mailing library. I like swift: http://www.swiftmailer.org/
    Thing is though, I always like to know exactly what's going on in my code. If i write it from scratch I can understand it and improve it. I also hate bloated code with features I don't need. This mailer will be part of a back end admin area I'm building to manage all my sites.

    Any help with the original post, please please please!

  6. #6
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I will doit this way:
    PHP Code:
    <?php 
        
    include '../../opendb.php';
        
        
    // Select db
        
    mysql_select_db($dbname1);

        
    $mailtable         $_POST['table'];
        
    $mailsubject     $_POST['subject'];
        
    $mailmessage    stripslashes($_POST['message']);

        
    $rs mysql_query("SELECT * FROM " $mailtable " WHERE flag = 0");
        
    $error false;
        
        while(
    $row mysql_fetch_assoc($rs)){
                
    extract($row);
                
                
    $header     "FROM: YourName<your@email.com>\r\n";
                
    $header .= "X-Mailer: PHP/" phpversion() . "\r\n";

                
    $message "Dear $name, \r\n";
                
    $message.= " \r\n";
                
    $message.= $mailmessage;
                
    $message.= " \r\n";
                
    $message.= "Warmest Regards \r\n";
                
    $message.= "YourName";
                
                
    $send mail($email$mailsubject$message$header);
                
                if(
    $send){
                    
    mysql_query("UPDATE $mailtable SET flag=1 WHERE email='" $email "' LIMIT 1");
                }else{
                    
    $error true;
                    echo 
    "Error sending to: " $email '<br>';
                }
        }
        
        if(!
    $error){
            
    // Set the flag back to zero if everything goes well
            
    mysql_query("UPDATE $mailtable SET flag=0 WHERE flag=1");
        }
        
        
    // The rest of your code
    ?>
    Like you can se I added a new flag to the table, this in case something goes wrong you will know who got the email and who dint.

    But to use the mail function to send over 2000 emails its a overload for your sever since the mail function connect to smtp server every time the function is used, thats means over 2000 connections in some seconds/minutes, thats a lot!

    So i prefer you te see some other alternatives, Zend_Mail is a good one or PHPMailer.

    Bye and happy holidays to all of you

  7. #7
    SitePoint Enthusiast
    Join Date
    Dec 2004
    Location
    uk
    Posts
    41
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    oxodesign, thank you very much!

    Thank you to everyone for your comments. Based on the above I have modified my script. The DB table now has a column to say whether the person wants to receive the newsletter or not and there is also a column to say whether they have already been emailed. I am also now limiting the script to 100 emails at a time.

    For anyone who is interested, here is the code. I am still open to improvements if anyone can spot any weakness ;-)

    Code:
    <?php
    include("../../opendb.php");
    mysql_select_db($dbname1);
    
    $mailtable = $_POST['table'];
    $mailsubject = $_POST['subject'];
    $mailmessage = stripslashes($_POST['message']);
    $maxsend = 100; 
    
    $sql="SELECT * FROM $mailtable WHERE send='0' AND receive='1' LIMIT $maxsend";
    $result=mysql_query($sql);
    while($rows=mysql_fetch_array($result)){
    	$name = $rows['name'];
    	$to = $rows['email'];
    	$subject = "$mailsubject";
    	$header = "from: Me <me@domain.com>";
    	$message = "Dear $name \r\n";
    	$message.= " \r\n";
    	$message.= "$mailmessage \r\n";
    	$message.=" \r\n";
    	$message.="Warmest Regards \r\n";
    	$message.="Name \r\n";
    	$sentmail=mail($to,$subject,$message,$header);
    	if($sentmail){
    	$query = "UPDATE $mailtable SET send='1' WHERE email='$to'";
    	$result2 = mysql_query($query);
    	echo "Email sent to: $to</br>";
    	}
    	else {
    	$query2 = "UPDATE $mailtable SET send='0' WHERE email='$to'";
    	$result3 = mysql_query($query2);
    	echo "Error sending to: $to</br>";
    	}
    }
    include("../../closedb.php");
    ?>

  8. #8
    SitePoint Wizard frank1's Avatar
    Join Date
    Oct 2005
    Posts
    1,392
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i think real answer to use queue making a new table and use cron to do the things..rather than others....


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •