Скрипт формы обратной связи с прикреплением файла (php + ajax)

(Обновлено 26.06.2018)

Данный скрипт идеально подойдет для форм при создании сайтов-визиток, каталогов, лендингов, где нужно отправить простую форму с прикрепленным файлом.

В скрипте используется проверка заполненности обязательных полей с помощью скрипта jquery.validation с последующей отправкой сообщения на e-mail администратора без перезагрузки страницы с помощью технологии ajax.

Демо-страницу можно посмотреть – тут.

Рассмотрим работу скрипта на примере:
Дана форма с полями: Имя, Телефон, Е-mail и "Описание заказа".

Код формы:

<form action="#" method="post" id="sendform" enctype="multipart/form-data">
  <fieldset>
    <h3>Форма заказа</h3>
    <p>
      <label>Имя*:</label>
      <input name="name" value="" size="40" type="text" class="required" />
    </p>

    <p> 
      <label>Контактный номер*:</label>
      <input name="tel" value="" size="40" class="required" type="tel" />
    </p>

    <p>
      <label>E-mail:</label>
      <input name="email" value="" size="40" type="email" />
    </p>

    <p>
      <label>Описание заказа:</label>
      <textarea name="message" cols="40" rows="10" /> </textarea>
    </p>

    <p>
      <label>Прикрепить файл:</label>
      <input name="file" value="1" size="40" type="file" />
    </p>

    <input value="Отправить" name="sendMail" type="submit" />
  </fieldset>
</form>

! В форме, в которой происходит прикрепление файла, обязательно наличие аттрибута enctype=”multipart/form-data”.

 

Javascript код

Подключаем библиотеки jQuery и плагин валидации на страницу:

<script src="https://code.jquery.com/jquery-1.12.4.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js" type="text/javascript"></script>

 

Javascript код для валидации и ajax-отправки формы

// Как только страничка загрузилась 
  window.onload = function () { 
    // проверяем поддерживает ли браузер FormData 
    if(!window.FormData) {
      alert("Браузер не поддерживает загрузку файлов на этом сайте");
    }
  }


$(document).ready(function(){
  // =validation
  var errorTxt = 'Ошибка отправки';
  $("#sendform").validate({
    submitHandler: function(form){
      var form = document.forms.sendform,
        formData = new FormData(form),
        xhr = new XMLHttpRequest();

      xhr.open("POST", "/send.php");
      
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
          if(xhr.status == 200) {
            $("#sendform").html('<p class="thank">Данные отправлены!<p>');
          }
        }
      };
      xhr.send(formData);
    }
  }); 
})

 

Разберем более подробно этот код.

Для отправки файлов используется интерфейс FormData. Для кодирования данных метод FormData использует формат “multipart/form-data”. Это означает то, что он позволяет подготовить для отправки по AJAX как текстовые данные, так и файлы. При создании объекта FormData ему можно в качестве параметра указать DOM форму. В этом случае в объект FormData автоматически добавятся все поля (имяПоля:значение) этой формы.

О более детальной работе FormData можно почитать тут.

После загрузки страницы, с помощью строки if(!window.FormData) проверяем доступность данного объекта. В случае, если он не доступен сообщаем об этом пользователю (для демонстрации в коде сообщение выводится алертом, на живом сайте так делать не надо – правильней будет в форме, скрывать поле для загрузки файлов). Это касается совсем старых браузеров. Для всех современных браузеров все будет работать.

При нажатии на кнопку “Отправить” проверяются обязательные поля на заполненность с помощью метода validate и в случае успешной проверки (submitHandler) создается новый объект FormData, происходит вызов скрипта send.php, который и производит отправку форму и прикрепленного к ней файла.

Затем вместо формы выводится сообщение об успешной отправке. За это отвечает строка

$("#sendform").html('<p class="thank">Данные отправлены!</p>');

 

PHP-скрипт отправки данных с формы

send.php

<?php
$to = 'info@proverstka.com.ua';

if ( isset( $_POST['sendMail'] ) ) {
  $name  = substr( $_POST['name'], 0, 64 );
  $tel = substr( $_POST['tel'], 0, 64 );
  $email   = substr( $_POST['email'], 0, 64 );
  $message = substr( $_POST['message'], 0, 250 );
 

  if ( !empty( $_FILES['file']['tmp_name'] ) and $_FILES['file']['error'] == 0 ) {
    $filepath = $_FILES['file']['tmp_name'];
    $filename = $_FILES['file']['name'];
  } else {
    $filepath = '';
    $filename = '';
  }
 
  $body = "Имя:\r\n".$name."\r\n\r\n";
  $body .= "Контактный номер:\r\n".$tel."\r\n\r\n";
  $body .= "E-mail:\r\n".$email."\r\n\r\n";
  $body .= "Описание заказа:\r\n".$message;
 
  send_mail($to, $body, $email, $filepath, $filename);
}

// Вспомогательная функция для отправки почтового сообщения с вложением
function send_mail($to, $body, $email, $filepath, $filename)
{
  $subject = 'Тестирование формы с прикреплением файла с сайта proverstka.com.ua';
  $boundary = "--".md5(uniqid(time())); // генерируем разделитель
  $headers = "From: ".$email."\r\n";   
  $headers .= "MIME-Version: 1.0\r\n";
  $headers .="Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n";
  $multipart = "--".$boundary."\r\n";
  $multipart .= "Content-type: text/plain; charset=\"utf-8\"\r\n";
  $multipart .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";

  $body = $body."\r\n\r\n";
 
  $multipart .= $body;
 
  $file = '';
  if ( !empty( $filepath ) ) {
    $fp = fopen($filepath, "r");
    if ( $fp ) {
      $content = fread($fp, filesize($filepath));
      fclose($fp);
      $file .= "--".$boundary."\r\n";
      $file .= "Content-Type: application/octet-stream\r\n";
      $file .= "Content-Transfer-Encoding: base64\r\n";
      $file .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
      $file .= chunk_split(base64_encode($content))."\r\n";
    }
  }
  $multipart .= $file."--".$boundary."--\r\n";
  mail($to, $subject, $multipart, $headers);
}
?>

 

Архив с примером
Демо-страница формы обратной связи с прикреплением файла


Дополнение от 28.12.2016

Отправка формы с прикреплением нескольких файлов

В элементе input, в котором прикрепляем файл, дописываем аттрибут multiple
(<input name=”file[]” value=”1″ size=”40″ type=”file” multiple />), что даст возможность выбора одновременно несколько файлов.

Изменяем php файл для обработки массива из нескольких файлов:

<?php
$to = 'info@proverstka.com.ua';

if ( isset( $_POST['sendMail'] ) ) {
	$name	= substr( $_POST['name'], 0, 64 );
	$tel = substr( $_POST['tel'], 0, 64 );
	$email	 = substr( $_POST['email'], 0, 64 );
	$message = substr( $_POST['message'], 0, 250 );

if($_FILES)
{
	$filepath = array();
	$filename = array();
	$i = 0;
		foreach ($_FILES["file"]["error"] as $key => $error) {
			if ($error == UPLOAD_ERR_OK) {
				$filename[$i][0] = $_FILES["file"]["tmp_name"][$key];
				$filename[$i][1] = $_FILES["file"]["name"][$key];
				$i++;
			}
		}
	}
	
	$body = "Имя:\r\n".$name."\r\n\r\n";
	$body .= "Контактный номер:\r\n".$tel."\r\n\r\n";
	$body .= "E-mail:\r\n".$email."\r\n\r\n";
	$body .= "Описание заказа:\r\n".$message; 
	send_mail($to, $body, $email, $filename);
}




// Вспомогательная функция для отправки почтового сообщения с вложением
function send_mail($to, $body, $email, $filename)
{
	$subject = 'Тестирование формы с прикреплением файла с сайта proverstka.com.ua';
	$boundary = "--".md5(uniqid(time())); // генерируем разделитель
	$headers = "From: ".$email."\r\n";	 
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .="Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n";
	$multipart = "--".$boundary."\r\n";
	$multipart .= "Content-type: text/plain; charset=\"utf-8\"\r\n";
	$multipart .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";

	$body = $body."\r\n\r\n";
 
	$multipart .= $body;
	foreach ($filename as $key => $value) {
		$fp = fopen($value[0], "r"); 
		$content = fread($fp, filesize($value[0]));
		fclose($fp);
		$file .= "--".$boundary."\r\n";
		$file .= "Content-Type: application/octet-stream\r\n";
		$file .= "Content-Transfer-Encoding: base64\r\n";
		$file .= "Content-Disposition: attachment; filename=\"".$value[1]."\"\r\n\r\n";
		$file .= chunk_split(base64_encode($content))."\r\n";
	}
	$multipart .= $file."--".$boundary."--\r\n";
	mail($to, $subject, $multipart, $headers);
}
?>

 

Демо-пример формы с прикреплением нескольких файлов на отдельной странице
Архив с примером

Loading Disqus Comments ...
Loading Facebook Comments ...

One thought on “Скрипт формы обратной связи с прикреплением файла (php + ajax)

  1. Владимир:

    —-0e1da19ddc73ed414d8185b01e2d2035

    Content-Type: application/octet-stream

    Content-Transfer-Encoding: base64

    Content-Disposition: attachment; filename=”03_вечер-4×4.png”

    iVBORw0KGgoAAAANSUhEUgAAB9AAAAUhCAIAAABcC4i7AACAAElEQVR42uzdh1JbWbOGYZGNbYKN

    yaAM2OOoBNJWIKNE8Pzn/u/lgGGwEAo7rNDd65t6ixKMkINS1eOmV+y8vCe7CwNVordPoUsWeaS7

    GtOB/Ko2a7reZ9SsIWQ2POnCdoUG5gXrEnmfL0JUUdKByc7tVtbVGeuOXnQauH2ynYTokFzHhtob

    UElxDdYVX1Q3WtZMtaAV2FRVViZYeaN5Msr5Kf1cBeXS5df9UlMMzk5A2y3L+yWjWCK7G/IOYYe/

    w9YRAsHD3y2xO/A9pLyTR3Za8l4Gu6ti930WyTD3E/PUrgfcjwWBuyl2zxpOsLnXDFO7JXOvygf3

    9OsA7vrMPQZqp6TtRuX9EtRuwdkl4juEHf4OW0cICg98J8PukPdL9ex+QDCwO2VzP2NO7ZHY/dAR

    dt8bXwnsbsvcsxaDuauhdkvgLtfc06ODuVcA7lScXbu2a5T3S1A7CWQXIe8Qdvg7eH14LSnBykHw
    ……………………. – вместо фото

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *