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

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

2 марта 2020 PHP

Мы уже рассматривали, как сделать форму обратной связи на 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 = "---";. Разделитель следует обозначить в отправляемых заголовках, и выводить до и после прикрепления файла в тексте письма.

eco-service.kz

<?
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 = "[email protected]"; // Ваш e-mail
	$subject = "Письмо с сайта"; // Тема сообщения
	$from = "[email protected]"; // Почта отправителя
	
	$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 "Сообщение не отправлено!"; 
    }
}
?>

Если вам понравилась статья, вы можете отблагодарить автора любой суммой, какую сочтете для себя приемлемой:
Остались вопросы по статье? Задайте их прямо сейчас!
Телеграм бот на PHP отправляющий сообщения с сайта

Что если сообщения с сайта будут приходить не только на ваш e-mail, но и моментально в мессенджер телеграм. Удобно же! Нужно было реализовать такой функционал, ну как и всегда все оказалось довольно просто. Так же стояла задача отправлять сообщения не Читать далее

Отправка формы без перезагрузки страницы на PHP и Ajax

Постоянно приходится пользоваться этой заготовкой. Вы можете модернизировать ее под любые нужды, будь то форма обратной связи, форма обратного звонка или заказ какой-либо услуги или товара. Поэтому я не буду украшать ее стилями, применять классы Bootstrap и различные скрипты, как Читать далее

Вывести на PHP месяц и день недели на русском

Довольно часто приходится сталкиваться с выводом названий месяцев и дней недели по-русски. При чем в различных вариантах, к примеру с полным названием или сокращенным, с большой буквы или с маленькой. Можно воспользоваться одним из этих 2 вариантов для вывода даты Читать далее

Парсер яндекс погоды на PHP

Рабочий пример PHP парсера, который получает погоду с Яндекса по ID города. Скрипт сохраняет данные в файле кеша на сайте, и обновляет его раз в час. Так же расскажу как выводить на сайте собственные иконки погоды вместо стандартных от Яндекса. Читать далее

Как встроить видео с YouTube канала на сайт

Для вывода списка видеозаписей из канала или плейлиста YouTube на сайте можно воспользоваться этим полностью рабочим решением на PHP. С помощью этой функции можно получить все необходимые данные видеозаписей: название, изображение и идентификатор видео. Вам понадобится идентификатор канала или плейлиста. Читать далее

Курсы доллара и евро с сайта Центробанка на PHP

Парсер получает курсы доллара и евро с сайта Центробанка каждые 24 часа и записывает их в файл кеша /log/course.txt Скрипт полностью готов к работе и не требует каких-либо дополнительных настроек. <? function loadCourse(){ define("tsCourse","15:00:00"); # Время смены курса центральным банком Читать далее

Календарь на PHP и Ajax

Пример календаря на PHP и Ajax с переключением месяцев. Можно использовать как заготовку для решения любых задач. Я использовал его для создания плагина календаря мероприятий на WordPress. Скрипт использует процедурный подход, но имеет разделенную структуру с шаблоном , что довольно Читать далее

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

  1. Иван:

    Код свой посмотри.
    Как он у тебя работать будет???
    Писака…

  2. Александр:

    Ты зачем в FormData объект jquery передаешь, бестолочь?

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