Jump to content

PHP Email Sends to Recipient Multiple Times


dachshund

Recommended Posts

Hi,

 

We have a PHP email form but when it's submitted it sends to the recipient three or four times. I've put the form below, if you can see any errors please let me know.

 

Thanks,

 
<div id="content">
<?php
 
$submit = mysql_real_escape_string($_GET['s']);
if ($submit == 'submit') {
?>
 
<?php
$email = mysql_real_escape_string($_POST['email']);
$name = mysql_real_escape_string($_POST['name']);
$trackingnumber = mysql_real_escape_string($_POST['trackingnumber']);
 
$to = $email;
$subject = 'Your Order Has Now Been Shipped';
if ($trackingnumber == '') {
$message = '<html> 
  <body bgcolor="#FFFFFF"> 
  
     <table width="600" border="0" cellpadding="0" cellspacing="0" align="center">
    
     <tr>
     <td align="center" width="100%" style="padding:16px 0px;">
     <img src="image address" />
     </td>
     </tr>
     
     <tr>
     <td align="center" style="font-family:Times New Roman, Times; font-size:12.5px; color:#000; padding:16px 0px;">
     '.$name.', your order has now been shipped and should arrive in the next few days.<br /><br />
     For any addition information about your order, please email <a href="mailto:our email" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times;">our email</a> quoting your name and order date and we will reply to you as soon as possible.<br /><br />
     Thank you,<br />
     </td>
     </tr>
    
    </table>
  </body> 
</html>';
}else {
$message = '<html> 
  <body bgcolor="#FFFFFF"> 
  
     <table width="600" border="0" cellpadding="0" cellspacing="0" align="center">
    
     <tr>
     <td align="center" width="100%" style="padding:16px 0px;">
     <img src="image address" />
     </td>
     </tr>
     
     <tr>
     <td align="center" style="font-family:Times New Roman, Times; font-size:12.5px; color:#000; padding:16px 0px;">
     '.$name.', your order has now been shipped and should arrive in the next few days.<br /><br />
     You can track your order <a href="http://www.royalmail.com/track-trace" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times; target="_blank">here</a> with reference number <u>'.$trackingnumber.'</u>.<br /><br />
     For any addition information about your order, please email <a href="mailto:our email" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times;">our email</a> quoting your name and order date and we will reply to you as soon as possible.<br /><br />
     Thank you,<br />
     </td>
     </tr>
    
    </table>
  </body> 
</html>';
}
    $headers .= "Content-type: text/html\r\n" .
'From: Store Name <email@email.com>' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();
 
mail($to, $subject, $message, $headers);
 
?>
 
<?php
}
?>
 
<ul>
<li>
<form method="post" action="?s=submit" name="email" enctype="multipart/form-data">
Name*
<p>
<input type="text" class="text_input" name="name">
</p>
 
 
<div class="input_section">
Email*
</div>
 
<p>
<input type="text" class="text_input" name="email">
</p>
 
<div class="input_section">
Tracking Number
</div>
 
<p>
<input type="text" class="text_input" name="trackingnumber">
</p>
 
</li>
</ul>
 
<div>
<input type="submit" value="Send Confirmation" class="submit_order">
</div>
</form>
<div class="clear"></div>
</div>

 
Edited by dachshund
Link to comment
Share on other sites

There isn't anything in this chunk of code that would send it more than once.  I assume this isn't the only code on the page.  Is this code inside a loop of any kind?  When you hit submit, is there other code on the page that is also executing cause of the posting?

 

Couple other things too, unless you are putting any of the posted data into a database further down the script, the use of mysql_real_escape_string is completely pointless.  This is especially true on the $_GET['s'].  That function is ONLY to help make it safe to put the data into a database, it has nothing to do with making it safe to compare against or display the data on any screen.

 

These 2 lines

$submit = mysql_real_escape_string($_GET['s']);
if ($submit == 'submit') {

Could simply be this cause you are setting what exact value the var needs to be and you are only comparing it's value.

if ($_GET['s'] == 'submit') {

Then, because the $name is being sent to a person that will display the data, in your $message var do this with the $name

htmlentities($name, ENT_QUOTES)

That will ensure that when it's displayed on the users side, if by some chance it did have executable code in the $name, it won't work when it's displayed.

Link to comment
Share on other sites

Hmm, that's very strange then. Thanks for pointing out potential shortenings of code. I'm having the same multiple email issue with this page, can you spot anything here? Here's all the code:

 

 

 
<?php
include "template/header.php";
?>
 
<?php
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-synch';
 
$tx_token = $_GET['tx'];
$auth_token = "token is here";
$req .= "&tx=$tx_token&at=$auth_token";
 
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
// If possible, securely post back to paypal using HTTPS
// Your PHP server will need to be SSL enabled
// $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
 
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
// read the body data 
$res = '';
$headerdone = false;
while (!feof($fp)) {
$line = fgets ($fp, 1024);
if (strcmp($line, "\r\n") == 0) {
// read the header
$headerdone = true;
}
else if ($headerdone)
{
// header has been read. now read the contents
$res .= $line;
}
}
 
// parse the data
$lines = explode("\n", $res);
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0) {
for ($i=1; $i<count($lines);$i++){
list($key,$val) = explode("=", $lines[$i]);
$keyarray[urldecode($key)] = urldecode($val);
}
// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment
$firstname = $keyarray['first_name'];
$lastname = $keyarray['last_name'];
$itemname = $keyarray['item_name'];
$amount = $keyarray['mc_gross'];
$email = $keyarray['payer_email'];
 
echo ("<div id='completed'>Thank you for your order</div>");
 
echo ("<div id='completed_total'>Total payment amount: £$amount</div>\n");
 
}
else if (strcmp ($lines[0], "FAIL") == 0) {
// log for manual investigation
}
 
}
 
fclose ($fp);
 
$to      = $email;
$subject = 'Confirmation of order from our store';
$message = '<html> 
  <body bgcolor="#FFFFFF"> 
  
    <table width="600" border="0" cellpadding="0" cellspacing="0" align="center">
    
     <tr>
     <td align="center" width="100%" style="padding:16px 0px;">
     <img src="image link" />
     </td>
     </tr>
     
     <tr>
     <td align="center" style="font-family:Times New Roman, Times; font-size:12.5px; color:#000; padding:16px 0px;">
     '.$firstname.' '.$lastname.', thank you for your order from the store.<br /><br />
     You should shortly receive an email from Paypal with your full order details.<br />
     For any information about your order, please email <a href="mailto:email" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times;">email</a> quoting your Paypal Transaction ID and we will reply to you as soon as possible. For delivery information <a href="address" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times;">click here</a>.<br /><br />
     Thank you.
     </td>
     </tr>
    
    </table>
  </body> 
</html>';
    $headers .= "Content-type: text/html\r\n" .
'From: HUH. Store <email>' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();
 
mail($to, $subject, $message, $headers);
 
?>
<div id="completed_text">
Your transaction has been completed and a confirmation email has been sent to you.<br />For more information about your order please email <a href="mailto:email">email</a>. For information about delivery times please <a href="email">click here</a>.
</div>
 
<?php
include "template/footer.php";
?>
 
Link to comment
Share on other sites

Nope nothing in there that would indicate multiples being sent.  Is that last code for the PayPal IPN?  It looks like it.  If it is specifically for the IPN service, that page should not have any html output.  It should only handle processing with zero browser output, cause the client will never see the this page cause only PayPal is running it, not the clients browser.

Link to comment
Share on other sites

Hi, yes it reloads and says "email sent successfully" - but perhaps you are right.

 

On another note, the emails sent include this at the top of the body (picture attached). They didn't used to - any ideas why and how to get rid of it?

 

Thanks in advance

 

KQAbQTI.png

Link to comment
Share on other sites

The email client that you're viewing the email with is probably adding that.

 

If Zane is correct (which is what I suspect as well), you can solve the multiple emails by using a nonce token. The basic principle is that when the form is loaded, a token is generated and stored in a session, as well as in a hidden form field. When the form is submitted, your processing code will compare the hidden token with the session token, and then delete the token from the session once the form is finished processing. Therefore, the first time the form is submitted the token will be correct, but subsequent requests will fail since the token has been deleted from the session.

Link to comment
Share on other sites

Hmm, ok I've testing it loads of times now and it's definitely not due to being clicked twice. Always sends two emails. Here's the full PHP code.  I think there must be something that's triggering a double send in there.

 

 

 
<?php include "header.php";
 
if($session){
?>
 
<div id="control_panel">
 
<div id="loggedon">
Control Panel
</div>
 
<div id="logout">
<a href="logout.php">Log Out</a>
</div>
 
<div class="clear"></div>
</div>
 
<div id="admin">
 
<?php
 
include "admin_left_column.php";
 
?> 
 
<div id="content">
<?php
 
$submit = mysql_real_escape_string($_GET['s']);
if ($submit == 'submit') {
?>
 
<?php
$email = mysql_real_escape_string($_POST['email']);
$name = mysql_real_escape_string($_POST['name']);
$trackingnumber = mysql_real_escape_string($_POST['trackingnumber']);
 
$to = $email;
$subject = 'Your Order Has Now Been Shipped';
if ($trackingnumber == '') {
$message = '<html> 
  <body bgcolor="#FFFFFF"> 
  
     <table width="600" border="0" cellpadding="0" cellspacing="0" align="center">
    
     <tr>
     <td align="center" width="100%" style="padding:16px 0px;">
     <img src="logo.jpg" />
     </td>
     </tr>
     
     <tr>
     <td align="center" style="font-family:Times New Roman, Times; font-size:12.5px; color:#000; padding:16px 0px;">
     '.$name.', your order  has now been shipped and should arrive in the next few days.<br /><br />
     For any addition information about your order, please email <a href="mailto:" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times;">store@</a> quoting your name and order date and we will reply to you as soon as possible.<br /><br />
     Thank you,<br />
     </td>
     </tr>
    
    </table>
  </body> 
</html>';
}else {
$message = '<html> 
  <body bgcolor="#FFFFFF"> 
  
     <table width="600" border="0" cellpadding="0" cellspacing="0" align="center">
    
     <tr>
     <td align="center" width="100%" style="padding:16px 0px;">
     <img src="logo.jpg" />
     </td>
     </tr>
     
     <tr>
     <td align="center" style="font-family:Times New Roman, Times; font-size:12.5px; color:#000; padding:16px 0px;">
     '.$name.', your order  has now been shipped and should arrive in the next few days.<br /><br />
     You can track your order <a href="http://www.royalmail.com/track-trace" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times; target="_blank">here</a> with reference number <u>'.$trackingnumber.'</u>.<br /><br />
     For any addition information about your order, please email <a href="mailto:" style="color:#39c; text-decoration:none; font-family:Times New Roman, Times;">store</a> quoting your name and order date and we will reply to you as soon as possible.<br /><br />
     Thank you,<br />
     </td>
     </tr>
    
    </table>
  </body> 
</html>';
}
    $headers .= "Content-type: text/html\r\n" .
'From: Store <noreply@blah.co.uk>' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();
 
mail($to, $subject, $message, $headers);
 
?>
You have sent a confirmation email to <?php echo $name; ?> at email address <?php echo $email; ?>. <img src="tick.jpg">
 
<!-- Otherwise -->
 
<?php
}
?>
 
<ul>
<li>
<form method="post" action="?s=submit" name="email" enctype="multipart/form-data">
Name*
<p>
<input type="text" class="text_input" name="name">
</p>
 
 
<div class="input_section">
Email*
</div>
 
<p>
<input type="text" class="text_input" name="email">
</p>
 
<div class="input_section">
Tracking Number
</div>
 
<p>
<input type="text" class="text_input" name="trackingnumber">
</p>
 
</li>
</ul>
 
<div>
<input type="submit" value="Send Confirmation" class="submit_order">
</div>
</form>
<div class="clear"></div>
</div>
 
<!-- END CONTENT -->
 
<div class="clear"></div>
</div>
 
<?php
}else {
 
if(!$_POST['login']){
 
?>
 
<div id="login_title">
Admin
</div>
 
<div id="login">
 
<ul>
 
<form method="post" action="#" name="login">
<li>
Username
<p><input type="text" name="username"></p>
</li>
<li>
Password
<p><input type="password" name="password"></p>
</li>
<li>
<input type="submit" class="submit" value="Log In" name="login">
<div class="clear"></div>
</li>
</form>
 
</ul>
 
</div>
 
<?php
 
}else {
$username = $_POST['username'];
$password = $_POST['password'];
 
if($username && $password){
$sql = "SELECT * FROM users WHERE `username`='$username'";
$res = mysql_query($sql) or die(mysql_error());
 
if(mysql_num_rows($res) == 1){
$epass = md5($password);
$sql2 = "SELECT * FROM users WHERE `username` = '$username' AND `password` = '$epass'";
$res2 = mysql_query($sql2) or die(mysql_error());
$rows = mysql_fetch_assoc($res2);
 
 
if(mysql_num_rows($res2) == 1){
//success
 
$_SESSION['admin'] = $rows['userid'];
echo 'You are logged in as ';
echo $username;
echo '.';
}else {
echo 'Wrong username and/or password';
}
 
}else {
echo 'Username does not exist.';
}
}else {
echo 'Please fill in all fields.';
}
}
}
?>
 
Link to comment
Share on other sites

sadly, browsers can request a page twice, for various reasons.

 

you should log information each time the code runs (using file_put_contents() with the FILE_APPEND flag) so that you will know who (if you have a login system, log the user id), what (log the $_GET, $_POST, and $_SERVER['REQUEST_METHOD']), when (log the date, time, and microtime), and where (log the $_SERVER['REMOTE_ADDR']) information about the request.

 

if the duplicate requests are close together (less than one second), they are likely being caused by the browser, in which case you don't have control over the cause of the problem. if only one of the duplicate requests contains the expected data, you will need to detect and use only the correct request.

Link to comment
Share on other sites

example code to log information about the request -

$log_file = 'log.txt';
$date = new DateTime();
list(,$us) = explode('.',microtime(true));  // unfortunately the 'u' format specifier returns zero for me, so use microtime() to get the fractional seconds
$dt = $date->format('Y-m-d H:i:s') . ".$us";

$log_this = "$dt\n";
$log_this .= "Usr: {$_SESSION['user_id']}\n";
$log_this .= "Rm: {$_SERVER['REQUEST_METHOD']}\n";
$log_this .= "Get: " . print_r($_GET,true);
$log_this .= "Post: " . print_r($_POST,true);
$log_this .= "Ip: {$_SERVER['REMOTE_ADDR']}\n\n";

file_put_contents($log_file, $log_this,FILE_APPEND);

add any other debugging information you may need, such as the entire $_SESSION array, $_SERVER['HTTP_USER_AGENT'], ...

Link to comment
Share on other sites

if you used that exact code and only got one set of data in the log file, but two emails, the problem isn't in the code you are showing us in this thread.

 

you either have some other code involved, that you haven't shown us, such as javascript/ajax in your form that's submitting to some other php code that also sends an email or an included file on the php side that is also contains a mail() statement, you could even have a header() redirect in the php code that you don't have an exit; statement after and some mail() code later in the file that's sending the second email, or the problem is something to do with your mail server, such as an auto-reply, email forwarding, or some logging function that's causing a duplicate to be sent to the same email address that you are using in the php code.

 

are the two emails completely identical? for the line you showed in reply #7, is the blocked out email address(s) in it the same or different from what you are using in the php code? we get that you don't want to show actual information, but tell us specifically, for each of those two blocked out pieces, how they did or did not relate to the to: and from: addresses that are being used in the php code.

Edited by mac_gyver
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.