2017-02-19 3 views
0

PHP 문의 양식은 페이지를 새로 고칠 때마다 전자 메일을 보냅니다. 사용자가 메시지를 한 번 보내고 다시 새로 고침하면 동일한 메시지가 다시 전송됩니다. 이는 페이지를 새로 고칠 때마다 발생합니다.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 = '[email protected]'; //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.'); 
     } 
    } 
} 

답변

1

$sender_lname = filter_var($_POST["fname"], FILTER_SANITIZE_STRING); 될 경우, $sender_lname = filter_var($_POST["lname"], FILTER_SANITIZE_STRING);

당신은 브라우저를 새로 고침하는 경우, 그들은 마지막 POST 요청을 캐시하는 경향이있다. 양식 데이터를 다시 제출할 것인지 묻는 메시지가 나타날 수 있습니다. 토큰에 해시 값이있는 숨겨진 필드를 추가하십시오.

<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. 

좋은 해싱 기능을 사용하여 토큰을 만드십시오. 나는 md5sha1을 명확하게 안내 할 것이다. 기본적으로

...
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'];)를 사용하여 조심. 대부분의 사람들은 그것을 사용하지 않는 방법을 찾아야한다고 말하지만, 그렇다면 어떤 방식 으로든 필터링하고 유효성을 검사해야합니다. 파일 이름을 다시 지정하는 것이 적절할 수 있습니다. 파일 크기를 확인하는 것도 좋은 생각입니다. 파일 크기 비트에 대해 php.ini에 너무 많이 의존하지 마십시오. 파일 유형이 중요한 경우 파일을 수락하기 전에 파일을 검사 할 수도 있습니다.

마지막으로, PHP 필터 함수를 사용하려는 경우 filter_input_array()INPUT_POST을 POST 데이터로 사용하는 것이 좋습니다. $_FILES superglobal의 경우, 검증을 위해 별도의 루틴을 만들었지 만 (filter_input_array()은 사용할 수 없습니다). 행운을 빕니다! 너는 너의 길에있어!

-1

당신이 웹 프로그래밍의 모범 사례 중 일부를 수행하지 않았기 때문에 그것은 형태마다 보냅니다

여기에 내 코드 양식 형태이다.

먼저 제출 된 양식에서 데이터를받은 후 사용자를 새 페이지로 리디렉션하여 요청 유형을 GET으로 변경하고 다음 제출을 방지해야합니다.

다음은 두 가지 상황 (즉, 이중 제출 및 CSRFattacks)을 방지하기 위해 CSRF token을 사용해야한다는 것입니다.