PHP 每次刷新页面时发送电子邮件的联系表
PHP contact form sending email every time the page is refreshed
PHP 每次刷新页面时联系表单都会发送电子邮件。如果用户发送一次他的消息并再次刷新,则再次发送相同的消息。每次刷新页面时都会发生这种情况。
这是我的代码形式:
if (isset($_POST['submit'])) {
if ($_POST['email'] == '' || $_FILES['file_upload'] == '' || $_POST["fname"] == '' || $_POST["lname"] == '' || $_POST["message"] == '') {
echo '<p class="red-info">Please Fill All The Fields</p>';
} else {
$from_email = $_POST['email']; //from mail, it is mandatory with some hosts
$recipient_email = 'myemail@gmail.com'; //recipient email (most cases it is your personal email)
//Capture POST data from HTML form and Sanitize them,
$sender_fname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING); //sender name
$sender_lname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING); //sender name
$sender_phone_1 = filter_var($_POST["phone_1"], FILTER_SANITIZE_STRING); //sender name
$sender_phone_2 = filter_var($_POST["phone_2"], FILTER_SANITIZE_STRING); //sender name
$sender_phone_3 = filter_var($_POST["phone_3"], FILTER_SANITIZE_STRING); //sender name
$sender_phone = $sender_phone_1 . ' ' . $sender_phone_2 . ' ' . $sender_phone_3; //sender name
$reply_to_email = filter_var($_POST["email"], FILTER_SANITIZE_STRING); //sender email used in "reply-to" header
$subject = 'Contact Form'; //get subject from HTML form
$message = filter_var($_POST["message"], FILTER_SANITIZE_STRING); //message
/* //don't forget to validate empty fields
if(strlen($sender_name)<1){
die('Name is too short or empty!');
}
*/
//Get uploaded file data
$file_tmp_name = $_FILES['file_upload']['tmp_name'];
$file_name = $_FILES['file_upload']['name'];
$file_size = $_FILES['file_upload']['size'];
$file_type = $_FILES['file_upload']['type'];
$file_error = $_FILES['file_upload']['error'];
if ($file_error > 0) {
die('Upload error or No files uploaded');
}
//read from the uploaded file & base64_encode content for the mail
$handle = fopen($file_tmp_name, "r");
$content = fread($handle, $file_size);
fclose($handle);
$encoded_content = chunk_split(base64_encode($content));
$boundary = md5("sanwebe");
//header
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From:" . $from_email . "\r\n";
$headers .= "Reply-To: " . $reply_to_email . "" . "\r\n";
$headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";
//plain text
$body = "--$boundary\r\n";
$body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= "<br />First Name:" . $sender_fname;
$body .= "<br />Last Name:" . $sender_lname;
$body .= "<br />Phone:" . $sender_phone;
$body .= "<br />Message:";
$body .= chunk_split(base64_encode($message));
//attachment
$body .= "--$boundary\r\n";
$body .= "Content-Type: $file_type; name=" . $file_name . "\r\n";
$body .= "Content-Disposition: attachment; filename=" . $file_name . "\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
$body .= "X-Attachment-Id: " . rand(1000, 99999) . "\r\n\r\n";
$body .= $encoded_content;
$sentMail = mail($recipient_email, $subject, $body, $headers);
if (isset($sentMail)) //output success or failure messages
{
echo '<p class="green-info">Your Email Has Been Submitted!We will contact soon.</p>';
echo "<script>document.contact.reset();</script>";
header("location: contect.php");
} else {
die('Could not send mail! Please check your PHP mail configuration.');
}
}
}
每次都发送表单,因为你没有遵循网络编程的一些良好做法。
首先,从提交的表单中收到数据后,您应该将用户重定向到新页面以将请求类型更改为 GET
并阻止下一次提交。
接下来就是你应该使用CSRF token
来防止两种情况:双重提交和CSRF
attacks.
$sender_lname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING);
应该是,$sender_lname = filter_var($_POST["lname"], FILTER_SANITIZE_STRING);
如果您正在刷新浏览器,它们往往会缓存最后一个 POST 请求。系统可能会询问您是否要 re-submit 表单数据。尝试为令牌添加一个带有哈希值的隐藏字段。
<input type="hidden" name="token" value="someHashValue">
实施会话以将提交的令牌与存储在 $_SESSION
中的令牌进行比较。
session_start();
session_regenerate_id(); //Used properly, helps deter session fixation;
$_SESSION['token'] = "someHashValue"; //Must be unique for each page load.
使用良好的散列函数创建令牌。我会避开 md5
和 sha1
.
基本上...
if($_SESSION['token'] === $_POST['token'])
{
//Good. You want to filter, validate, and check this early on.
//Whatever you do, just be consistent.
}
此外,请注意不要在代码中使用浏览器提供的文件名 ($file_name = $_FILES['file_upload']['name'];
)。大多数人会说找到一种不使用它的方法,但如果你这样做,你仍然需要以某种方式过滤和验证它。 Re-naming 该文件可能是合适的。检查文件大小也是一个好主意。不要过分依赖 php.ini
文件大小位。如果文件类型很重要,您甚至可以在接受之前尝试检查文件。
最后,当你到达那里时,如果你打算使用 PHP 过滤功能,最好将 filter_input_array()
与 INPUT_POST
一起用于你的 POST 数据。对于 $_FILES
超全局,我制作了一个单独的例程来验证它(但是,您不能为此使用 filter_input_array()
)。祝你好运!您正在路上!
PHP 每次刷新页面时联系表单都会发送电子邮件。如果用户发送一次他的消息并再次刷新,则再次发送相同的消息。每次刷新页面时都会发生这种情况。
这是我的代码形式:
if (isset($_POST['submit'])) {
if ($_POST['email'] == '' || $_FILES['file_upload'] == '' || $_POST["fname"] == '' || $_POST["lname"] == '' || $_POST["message"] == '') {
echo '<p class="red-info">Please Fill All The Fields</p>';
} else {
$from_email = $_POST['email']; //from mail, it is mandatory with some hosts
$recipient_email = 'myemail@gmail.com'; //recipient email (most cases it is your personal email)
//Capture POST data from HTML form and Sanitize them,
$sender_fname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING); //sender name
$sender_lname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING); //sender name
$sender_phone_1 = filter_var($_POST["phone_1"], FILTER_SANITIZE_STRING); //sender name
$sender_phone_2 = filter_var($_POST["phone_2"], FILTER_SANITIZE_STRING); //sender name
$sender_phone_3 = filter_var($_POST["phone_3"], FILTER_SANITIZE_STRING); //sender name
$sender_phone = $sender_phone_1 . ' ' . $sender_phone_2 . ' ' . $sender_phone_3; //sender name
$reply_to_email = filter_var($_POST["email"], FILTER_SANITIZE_STRING); //sender email used in "reply-to" header
$subject = 'Contact Form'; //get subject from HTML form
$message = filter_var($_POST["message"], FILTER_SANITIZE_STRING); //message
/* //don't forget to validate empty fields
if(strlen($sender_name)<1){
die('Name is too short or empty!');
}
*/
//Get uploaded file data
$file_tmp_name = $_FILES['file_upload']['tmp_name'];
$file_name = $_FILES['file_upload']['name'];
$file_size = $_FILES['file_upload']['size'];
$file_type = $_FILES['file_upload']['type'];
$file_error = $_FILES['file_upload']['error'];
if ($file_error > 0) {
die('Upload error or No files uploaded');
}
//read from the uploaded file & base64_encode content for the mail
$handle = fopen($file_tmp_name, "r");
$content = fread($handle, $file_size);
fclose($handle);
$encoded_content = chunk_split(base64_encode($content));
$boundary = md5("sanwebe");
//header
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From:" . $from_email . "\r\n";
$headers .= "Reply-To: " . $reply_to_email . "" . "\r\n";
$headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";
//plain text
$body = "--$boundary\r\n";
$body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= "<br />First Name:" . $sender_fname;
$body .= "<br />Last Name:" . $sender_lname;
$body .= "<br />Phone:" . $sender_phone;
$body .= "<br />Message:";
$body .= chunk_split(base64_encode($message));
//attachment
$body .= "--$boundary\r\n";
$body .= "Content-Type: $file_type; name=" . $file_name . "\r\n";
$body .= "Content-Disposition: attachment; filename=" . $file_name . "\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
$body .= "X-Attachment-Id: " . rand(1000, 99999) . "\r\n\r\n";
$body .= $encoded_content;
$sentMail = mail($recipient_email, $subject, $body, $headers);
if (isset($sentMail)) //output success or failure messages
{
echo '<p class="green-info">Your Email Has Been Submitted!We will contact soon.</p>';
echo "<script>document.contact.reset();</script>";
header("location: contect.php");
} else {
die('Could not send mail! Please check your PHP mail configuration.');
}
}
}
每次都发送表单,因为你没有遵循网络编程的一些良好做法。
首先,从提交的表单中收到数据后,您应该将用户重定向到新页面以将请求类型更改为 GET
并阻止下一次提交。
接下来就是你应该使用CSRF token
来防止两种情况:双重提交和CSRF
attacks.
$sender_lname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING);
应该是,$sender_lname = filter_var($_POST["lname"], FILTER_SANITIZE_STRING);
如果您正在刷新浏览器,它们往往会缓存最后一个 POST 请求。系统可能会询问您是否要 re-submit 表单数据。尝试为令牌添加一个带有哈希值的隐藏字段。
<input type="hidden" name="token" value="someHashValue">
实施会话以将提交的令牌与存储在 $_SESSION
中的令牌进行比较。
session_start();
session_regenerate_id(); //Used properly, helps deter session fixation;
$_SESSION['token'] = "someHashValue"; //Must be unique for each page load.
使用良好的散列函数创建令牌。我会避开 md5
和 sha1
.
基本上...
if($_SESSION['token'] === $_POST['token'])
{
//Good. You want to filter, validate, and check this early on.
//Whatever you do, just be consistent.
}
此外,请注意不要在代码中使用浏览器提供的文件名 ($file_name = $_FILES['file_upload']['name'];
)。大多数人会说找到一种不使用它的方法,但如果你这样做,你仍然需要以某种方式过滤和验证它。 Re-naming 该文件可能是合适的。检查文件大小也是一个好主意。不要过分依赖 php.ini
文件大小位。如果文件类型很重要,您甚至可以在接受之前尝试检查文件。
最后,当你到达那里时,如果你打算使用 PHP 过滤功能,最好将 filter_input_array()
与 INPUT_POST
一起用于你的 POST 数据。对于 $_FILES
超全局,我制作了一个单独的例程来验证它(但是,您不能为此使用 filter_input_array()
)。祝你好运!您正在路上!