PHP mail() + Loop + Unsubscribe link

Hey everyone! ;D

I am working on a small/simple email subscribe-unsubscribe script. I have everything working the way I want it, mostly. When an admin would like to send out a message to all of the subscribers, it needs to add the unsubscribe link to the end of the message. My code is doing this, however, it then sends the next person in the list all of the pervious recipients unsubscribe links. I am really at a loss here, can anyone spot what is wrong? Any help is greatly appreciated!!! Thanks in advance.

[php]<?php
$cansend = $_POST[“canSend”];
if($cansend == 1)
{
$mailfrom = "[email protected]";
$mailsubject = mysql_real_escape_string($_POST[“txtSubject”]);
$mailbody = mysql_real_escape_string($_POST[“txtBody”]);
//$mailsto is a with values filled out from users table,
//one of the options selects everyone from the table separated, by, commas.
$mailsto = mysql_real_escape_string($_POST[“txtMailTo”]);
$mailarray = split(",",$mailsto);
$headers = “MIME-Version: 1.0\r\n”;
$headers .= “Content-type: text/html; charset=iso-8859-1\r\n”;
$headers .= “From: $mailfrom\r\n”;
foreach($mailarray as $mailto)
{
// this is where I am running in to problems,
// the script correctly selects the hash and email from the table
//however, for each iteration of the loop it sends the all previous
//persons unsubscribe link to the next persons email.

                    $query = mysql_query("SELECT hash FROM users where email=\"$mailto\"");
                    $hash = mysql_fetch_array($query);
                    $mailbody .= "Don't like these annoying emails? <a href=\"http://domain.com/unsubscribe.php?id=" . $hash[0] . "\">Unsubscribe</a>";
                    if(mail($mailto,$mailsubject,$mailbody,$headers))
                    {
                            $status = 1;
                    }
                    else
                    {
                            $status = 2;
                            $problemid .= $mailto;
                    }
            }
            if($status == 1){
                    echo "<div class=\"alert alert-block alert-success\">
                            <button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>
                            <h4>Success!</h4>
                            Your message has been sent...
                    </div>";
                    }
            else{
                    echo "<div class=\"alert alert-block alert-error\">
                            <button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>
                            <h4>Error!</h4>
                            Your message has not been sent...
                    </div>";
                    }
            }
            ?>[/php]

That’s really strange, the code looks as if it should work as you say it should. I’m interested to find out what the issue is. Hopefully, someone will be able to identify what’s wrong.

The reason looks to be found here.

[php] $mailbody .= [/php]

You are adding the new line each time the loop iterates.

Another way to handle this is to create an email template. Use things like ?body? And then srt_replace to place the needed values in their respective fields.

@astonecipher I can’t believe I didn’t catch that…

Thanks for the replies!

Could you point me in the right direction to get the Template/STR_REPLACE approach working?
Does this look like what you’re suggesting?


The phpfreaks post is what I am referring to.

Great, I will read more about this and see if I can get it working.

Here we go…

This no longer adds multiple links in the email (check :slight_smile: )
It is correctly finding the ##HASH## placeholder, and it is replacing it with a value from the database ( check :slight_smile: )

[b]My problem now is; When sending to multiple addresses, it is just sending the same value for every message (the first one it looks up) but if I uncomment the echo, it is displaying the correct email-hash pairs. :-[/b]

I feel like I’m taking crazy pills here! ha ha

[php]<?php
$cansend = $_POST[“canSend”];
if($cansend == 1)
{
$mailfrom = “[email protected]”;
$mailsubject = mysql_real_escape_string($_POST[“txtSubject”]);
$mailbody = mysql_real_escape_string($_POST[“txtBody”]);
$mailbody .= “Don’t like these annoying emails? <a href=“http://domain.com/unsubscribe.php?id=##HASH##”>Unsubscribe”;

		$mailsto = mysql_real_escape_string($_POST["txtMailTo"]);
		$mailarray = explode(",", $mailsto);
		
		$headers = "MIME-Version: 1.0\r\n";
		$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
		$headers .= "From: $mailfrom\r\n";
			
	foreach($mailarray as $mailto)
	{
		//Query for HASH
		$query = mysql_query("SELECT hash FROM users WHERE email=\"$mailto\"");
		$hash = mysql_fetch_array($query);
		
		//Find placeholder from message
		$find  = "##HASH##";
		
		//Replace with database selection
		$replace = $hash[0];
		
		//Call the str_replace function
		$mailbody = str_replace($find, $replace, $mailbody); 

//echo $mailto."|".$replace."
";

                   //Send the mail
		if(mail($mailto,$mailsubject,$mailbody,$headers))
		{
			$status = 1;
		}
		else
		{
			$status = 2;
			$problemid .= $mailto;
		}
	}
	
	if($status == 1){
		echo "<div class=\"alert alert-block alert-success\">
			<button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>
			<h4>Success!</h4>
			Your message has been sent...
		</div>";
		}
	else{
		echo "<div class=\"alert alert-block alert-error\">
			<button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>
			<h4>Error!</h4>
			Your message has not been sent...
		</div>";
		}
	} 
	?>[/php]

Try clearing the $replace value just before the loop closing bracket. I am on the run so I can’t test anything right now for a better option.

The next thing would be use prepared statements and upgrade from mysql_ to pdo or mysqli_

:slight_smile: :smiley: :wink: ;D Hooray!

There was actually nothing wrong with the last piece of code I posted, using the str_replace method. I just had messed up the haystack variable.

Doesn’t Work:
[php]
//Call the str_replace function
$mailbody = str_replace($find, $replace, $mailbody);

 //Send Mail
 if(mail($mailto,$mailsubject,$mailbody,$headers))
      ...

[/php]

Works:
[php]
//Call the str_replace function
$newMessage = str_replace($find,$replace,$mailbody);

//Send Mail
if(mail($mailto,$mailsubject,$newMessage,$headers))
...

[/php]

Again, thank you so so much for pointing me in the right direction!!

Sponsor our Newsletter | Privacy Policy | Terms of Service