Skip to main content

Отправка письма с вложениями на PHP и AJAX

Отправка письма с вложениями на PHP и AJAX

Мы уже рассматривали, как сделать форму обратной связи на PHP и Ajax. Сегодня мы модернизируем её и научим отправлять приложенные файлы.

HTML-код формы

Добавляем в форму ещё одно поле файл:

<form id="feedback-form" action="">
	<input type="text" name="name" required placeholder="Ваше имя">
	<input type="tel" name="phone" required placeholder="Ваш телефон">
	<textarea name="text" placeholder="Ваш текст"></textarea>
	<input type="file" name="file" required />
	<input type="submit" name="submit" value="Отправить">
</form>

JavaScript код с jQuery Ajax

Не забудьте перед кодом подключить библиотеку jQuery!

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

Отправляем данные с помощью объекта FormData — предназначенного для кодирования данных, которые необходимо отправить на сервер посредством технологии AJAX (XmlHttpRequest). Для кодирования данных метод FormData использует формат multipart/form-data. Это означает то, что можно подготовить для отправки по AJAX не только текстовые данные, но и файлы (input с атрибутом type="file").

<script>
$(document).ready(function () {
    $("form").submit(function () {
    // Получение ID формы
    var formID = $(this).attr('id');
    // Добавление решётки к имени ID
    var formNm = $('#' + formID);
    $.ajax({
      type: "POST",
      url: '/send.php',
      data: new FormData(formNm),
	  processData: false,
	  contentType: false,

      beforeSend: function () {
        // Вывод текста в процессе отправки
        $(formNm).html('<p style="text-align:center">Отправка...</p>');
      },
      success: function (data) {
        // Вывод текста результата отправки
        $(formNm).html('<p style="text-align:center">'+data+'</p>');
      },
      error: function (jqXHR, text, error) {
        // Вывод текста ошибки отправки
        $(formNm).html(error);
      }
    });
    return false;
  });
});
</script>

PHP обработчик

Файлы, которые будут отправлены, необходимо закодировать в формат base64 и указать в заголовках информацию о том, что в письме присутствуют файлы.

Чтобы отделить закодированный файл от текста письма, необходимо добавить текстовый разделитель, это может быть любая уникальная строка, в нашем случае $boundary = "---";. Разделитель следует обозначить в отправляемых заголовках, и выводить до и после прикрепления файла в тексте письма.

<?
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' && !empty($_POST['name'])) {
    $message = 'Имя: ' . $_POST['name'] . ' ';
    $message .= 'Телефон: ' . $_POST['phone'] . ' ';
	if(!empty($_POST['text'])) {
		$message = 'Текст: ' . $_POST['text'] . ' ';
	}
	
	$mailTo = "mail@mail.ru"; // Ваш e-mail
	$subject = "Письмо с сайта"; // Тема сообщения
	$from = "info@site.ru"; // Почта отправителя
	
	$boundary = "---"; //Разделитель
	/* Заголовки */
	$headers = "From: $from\nReply-To: $from\n";
	$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"";
	$body = "--$boundary\n";
	/* Присоединяем текстовое сообщение */
	$body .= "Content-type: text/html; charset='utf-8'\n";
	$body .= "Content-Transfer-Encoding: quoted-printablenn";
	$body .= "Content-Disposition: attachment; filename==?utf-8?B?".base64_encode($filename)."?=\n\n";
	$body .= $message."\n";
	$body .= "--$boundary\n";
	
	if ($_FILES['file']['error'] == UPLOAD_ERR_OK) {
		// получаем расширение исходного файла
		$ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
		// получаем уникальное имя под которым будет сохранён файл 
		$filename = md5(uniqid('', true)).'.'.$ext;
		// перемещаем файл из временного хранилища в указанную директорию
		if (move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$filename)) {
			
			$file = fopen($filename, "r"); //Открываем файл
			$text = fread($file, filesize($filename)); //Считываем весь файл
			fclose($file); //Закрываем файл
			
		}
	}
	
	/* Добавляем тип содержимого, кодируем текст файла и добавляем в тело письма */
	$body .= "Content-Type: application/octet-stream; name==?utf-8?B?".base64_encode($filename)."?=\n";
	$body .= "Content-Transfer-Encoding: base64\n";
	$body .= "Content-Disposition: attachment; filename==?utf-8?B?".base64_encode($filename)."?=\n\n";
	$body .= chunk_split(base64_encode($text))."\n";
	$body .= "--".$boundary ."--\n";
	
    if(mail($mailTo, $subject, $body, $headers)) {
        echo "Спасибо! Мы свяжемся с вами в самое ближайшее время!"; 
    } else {
        echo "Сообщение не отправлено!"; 
    }
}
?>
Похожие записи
Сохранение данных в форме после обновления страницы

Часто ли у вас случалось такое, что при заполнении формы на сайте истекал срок действия... Читать далее

Кастомный виджет переводчик для сайта с флагами

Сегодня мы кастомизируем стандартный виджет Google переводчика для сайта и сделаем его в виде меню... Читать далее

AJAX в 1C-Битрикс

В компонентах Битрикс есть встроенный функционал для AJAX подгрузки. Его так же можно использовать, например... Читать далее

Простая пагинация на PHP и MySQL

Это руководство о том, как сделать простое разбиение на страницы, используя PHP и MySQL с... Читать далее

Всплывающее окно при закрытии страницы

Стоп-форма - это всплывающее окно, призывающее к действию, которое открывается через определенное время нахождения пользователя... Читать далее

Календарь в input для ввода даты

Чтобы при вводе даты в input выпадал удобный календарик можно воспользоваться двумя способами: стандартным полем... Читать далее

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

*

code