Форма обратной связи с прикреплением файла (Send attachments with PHP Mail())

Форма обратной связи с прикреплением файла (attach)

Самый простой внешний вид формы обратной связи с тремя полями и полем для прикрепления файла:

<form id="feedback-form" enctype="multipart/form-data" method="post">
  <div class="form-group">
    <label for="nameFF">Name</label>
    <input id="nameFF" name="nameFF" type="text" placeholder=" " required>
  </div>
  <div class="form-group">
    <label for="contactFF">E-mail</label>
    <input id="contactFF" name="contactFF" type="email" placeholder=" " required>
  </div>
  <div class="form-group">
    <label for="projectFF">About your Project</label>
    <input id="projectFF" name="projectFF" type="text" placeholder=" " required>
  </div>
  <div class="control-file">
    <label for="fileFF">Attach file</label>
    <input id="fileFF" name="fileFF" type="file">
  </div>
  <button class="btn" type="submit" id="submitFF">Send</button>
</form>

Даже добавим пару правил для стилей, чтобы форма была понятного вида:

<style>
  label{
    display: block;
    margin: 20px 0 2px;
  }
  .btn{
    margin: 20px 0 0;
  }
</style>

Самое главное содержимое файла mail.php

<?php
if (isset ($_POST['contactFF'])) {
  $to = "to@gmail.com";
  $from = "from@gmail.com";
  $subject = "Заполнена контактная форма на сайте ".$_SERVER['HTTP_REFERER'];
  $message = "Имя: ".$_POST['nameFF']."\nКонтакты ".$_POST['contactFF']."\nПроект: ".$_POST['projectFF']."\n\nIP: ".$_SERVER['REMOTE_ADDR'];

  $boundary = md5(date('r', time()));
  $filesize = '';
  $headers = "MIME-Version: 1.0\r\n";
  $headers .= "From: " . $from . "\r\n";
  $headers .= "Reply-To: " . $from . "\r\n";
  $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
  $message="
Content-Type: multipart/mixed; boundary=\"$boundary\"

--$boundary
Content-Type: text/plain; charset=\"utf-8\"
Content-Transfer-Encoding: 7bit

$message";
     if(is_uploaded_file($_FILES['fileFF']['tmp_name'])) {
         $attachment = chunk_split(base64_encode(file_get_contents($_FILES['fileFF']['tmp_name'])));
         $filename = $_FILES['fileFF']['name'];
         $filetype = $_FILES['fileFF']['type'];
         $filesize = $_FILES['fileFF']['size'];
         $message.="

--$boundary
Content-Type: \"$filetype\"; name=\"$filename\"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=\"$filename\"

$attachment";
     }
   $message.="
--$boundary--";

  if ($filesize < 10000000) { // проверка на общий размер всех файлов. Многие почтовые сервисы не принимают вложения больше 10 МБ
    mail($to, $subject, $message, $headers);
    echo $_POST['nameFF'].', Ваше сообщение отправлено, спасибо!';
  } else {
    echo 'Извините, письмо не отправлено. Размер всех файлов превышает 10 МБ.';
  }
}
?>

Содержимое файла mail.js, перед подключением этого файла, подключаем jQuery.

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

Затем скрипт mail.js

$(function() {

  // E-mail Ajax Send
  // http://denis-creative.com/contact-form-with-attached-file/
  // http://shpargalkablog.ru/2014/05/email-file-php.html
  // http://shpargalkablog.ru/2014/05/feedback-form-file.html
  document.getElementById('feedback-form').addEventListener('submit', function(evt){
    var http = new XMLHttpRequest(), f = this;
    var th = $(this);
    evt.preventDefault();
    http.open("POST", "mail.php", true);
    http.onreadystatechange = function() {
      if (http.readyState == 4 && http.status == 200) {
        alert(http.responseText);
        if (http.responseText.indexOf(f.nameFF.value) == 0) { // очистить поля формы, если в ответе первым словом будет имя отправителя (nameFF)
          th.trigger("reset");
        }
      }
    }
    http.onerror = function() {
      alert('Извините, данные не были переданы');
    }
    http.send(new FormData(f));
  }, false);

});
Как настроить VPN в браузере Opera

В общем, из-за санкций против российских компаний возникли некоторые сложности у многих украинских компаний. Допустим,…

Простой jQuery-скрипт для табов (вкладок)

Самый простой пример реализации табов на сайте. Код максимально простой и легкий, не нужно никаких…

Какой размер для фавиконок использовать?

Чтобы далеко не ходить, сразу укажу, что остановился я на трех таких размерах для фавиконок,…

Фиксированное меню при прокрутке страницы только для мобильных

Немного другая вариация фиксированного меню. Меню фиксируется к верхней части экрана только на мобильных устройствах….

22 комментария

Дмитрий

Доброго времени ! Форма просто супер, даже без танцев с бубном, как это обычно бывает !!!

Подскажите а как сделать чтобы и людям, отправившим запрос, приходило письмо к примеру от webmaster@домен
с такими же данными и припиской в конце:

Спасибо за обращение!
В ближайшее время наши сотрудники свяжутся с Вами.
Это сообщение отправлено с сайта (в скобках ссылка на сайт)

Буду очень признателен если поможете. Уже создал папку с закладками вашего блога …

Владимир

Салют!
Благодарю за материал.
Вопрос: Почему не срабатывает оповещение о превышении лимита?
OpenServer Apache 2.4, PHP 5.6

JulieNeuch

День добрый.
Спасибо за ресурс.

Ольга

Обычно требуется прикрепить файл, выбрав с компьютера, но мне нужно прикрепить жестко только один файл, и не с компьютера, а с сайта, на котором расположена форма обратной связи. Можно ли, в принципе, это сделать, и как?

К сожалению, не подскажу.
Если файл уже находится на внешнем ресурсе, а не на компьютере, тогда может проще просто давать ссылку в письме?..

Почему-то файлы в pdf не отправляются((

А в другом формате отправляются?

Картинки jpg отправляются, другие не смотрела форматы…

Не знаю, в коде формы нет никакого фильтра по форматам файлов. Возможно настройки хостинга, можете обратиться в ТП хостинга, может они помогут, если сама форма работает и другие форматы отправляет.

Владимир

Почему приходят пустые файлы? т.е. весят 0 байт

Тестировал на разных сайтах и серверах, проблем не замечал, главное, не менять код, потому как при попытке «красиво отформатировать» файл mail.php — он совсем переставал работать. Поэтому попробуйте поменять только адресата и отправителя, а сам код не изменять.

Владимир

Так и делаю, все равно приходит пустой файл, и еще не приходят другие данные с формы (имя,емаил,о проекте), т.е. в письме только файл(пустой) и ip отправителя

Может какие-то настройки хостинга, точно не скажу, не сталкивался…
Попробуйте, если есть возможность, свой код на другом сервере.

Владимир

Буду разбираться, но все равно Спасибо за помощь

Владимир

Очень странно, на почте gmail все работает отлично, вот на яндекс.почте все именно так как я описывал

Если хостинг в Украине, тогда могут быть такие проблемы с Yandex и Mail.ru

Hello i am new user and i would to ask you, How to disable avatar?

Елена

Пристроила проверку на заполнение полей к скрипту. Теперь отпрравка формы получается только после второго нажатия на кнопку. Можете подсказать, в чем дело?

$("#form-help").validate({
  rules: {
    nameFF: "required",
    phoneFF: "required",
    emailFF: "required",
    message: "required",
  },
  messages: {
    nameFF: "<p style='font-size:10px; color:red;'>Укажите Ваше имя.</p>",
    phoneFF: "<p style='font-size:10px; color:red;'>Укажите Ваш номер телефона.</p>",
    emailFF: "<p style='font-size:10px; color:red;'>Укажите Ваш email.</p>",
    message: "<p style='font-size:10px; color:red;'>Опишите задачу.</p>",
  },
  
  submitHandler: function(form){

    document.getElementById('form-help').addEventListener('submit', function(evt){
      var http = new XMLHttpRequest(), f = this;
      var th = $(this);
      evt.preventDefault();
      http.open("POST", "help.php", true);
      http.onreadystatechange = function() {
        if (http.readyState == 4 && http.status == 200) {
          alert(http.responseText);
          if (http.responseText.indexOf(f.nameFF.value) == 0) {
            th.trigger("reset");
          }
        }
      }
      http.onerror = function() {
        alert('Извините, данные не были переданы');
      }
      http.send(new FormData(f));
    }, false);
  }
});

Извините, не могу. Нет времени проверять чужой код на ошибки.

Годнота

Have you ever thought about adding a little
bit more than just your articles? I mean, what you say is fundamental
and everything. Nevertheless think of if you added some great pictures or
video clips to give your posts more, «pop»! Your content is
excellent but with images and videos, this site could certainly be one of the greatest in its field.
Terrific blog!

Thanks for the idea, I’ll try to add more graphic content. It’s just that I have hundreds of notes in drafts, and there is no time to arrange even the text, not to mention the pictures or videos, but the idea is worthwhile.

Ответить