dachshund Posted June 27, 2015 Share Posted June 27, 2015 (edited) 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 June 27, 2015 by dachshund Quote Link to comment Share on other sites More sharing options...
fastsol Posted June 27, 2015 Share Posted June 27, 2015 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. Quote Link to comment Share on other sites More sharing options...
dachshund Posted June 27, 2015 Author Share Posted June 27, 2015 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"; ?> Quote Link to comment Share on other sites More sharing options...
fastsol Posted June 27, 2015 Share Posted June 27, 2015 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. Quote Link to comment Share on other sites More sharing options...
dachshund Posted June 27, 2015 Author Share Posted June 27, 2015 ok thanks for your help that page does show to the client, but only the echoed parts such as: echo ("<div id='completed'>Thank you for your order</div>"); echo ("<div id='completed_total'>Total payment amount: £$amount</div>\n"); Quote Link to comment Share on other sites More sharing options...
Zane Posted June 27, 2015 Share Posted June 27, 2015 Perhaps it isn't sending multiple emails, but rather, the form submit button is being clicked multiple times. Do you notify the user after the form has sent successfully? If you don't, then the problem is the UIX. Quote Link to comment Share on other sites More sharing options...
dachshund Posted July 3, 2015 Author Share Posted July 3, 2015 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 Quote Link to comment Share on other sites More sharing options...
scootstah Posted July 3, 2015 Share Posted July 3, 2015 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. Quote Link to comment Share on other sites More sharing options...
dachshund Posted July 4, 2015 Author Share Posted July 4, 2015 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.'; } } } ?> Quote Link to comment Share on other sites More sharing options...
scootstah Posted July 4, 2015 Share Posted July 4, 2015 There's nothing there that would cause mail to be sent twice. You're either executing the page twice, or you have some weird mail server issue that I've never heard of before. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted July 4, 2015 Share Posted July 4, 2015 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. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted July 4, 2015 Share Posted July 4, 2015 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'], ... Quote Link to comment Share on other sites More sharing options...
dachshund Posted July 6, 2015 Author Share Posted July 6, 2015 ok, tried that. in the txt file it says: 2015-07-06 17:42:07.4545 Usr: Rm: POST Get: Array ( => submit ) Post: Array ( [name] => Test => test@test.co.uk [trackingnumber] => test ) Ip: IP was here Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted July 6, 2015 Share Posted July 6, 2015 (edited) 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 July 6, 2015 by mac_gyver Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.