В этой статье рассмотрим как подключить на сайт готовый скрипт формы обратной связи и настроить его под свои поля. Данный скрипт написан на PHP, AJAX и jQuery.

Назначение и основные характеристики формы обратной связи

Форма обратной связи (feedback form) — это один из способов связи клиентов (посетителей сайта) с менеджерами или организаторами ресурса.

С помощью неё можно очень удобным способом получать первоначальные сведения о желании посетителей заказать какие-то определённые услуги или товары. Её можно использовать для сбора отзывов, идей, различных предложений и любой другой информации.

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

Контактная форма состоит из полей. Это процесс детализации позволяет чётко определить данные, которые нужно указать пользователю. Кроме этого, нет необходимости вводить электронную почту администратора или менеджера ресурса, т.е. email адрес куда эту информацию нужно отправить.

Основные характеристики этой php контактной формы:

  • работа без перезагрузки страницы (через ajax);
  • наличие защиты от спама (с помощью капчи);
  • возможность добавления к данным для отправки файлов;
  • валидация (проверка) данных, которая выполняется как на стороне клиента (в браузере), так и на стороне сервера;
  • отправка данных на почту (добавленные файлы можно настроить так, чтобы они приходили как посредством вложений, так и в виде ссылок в теле письма);
  • сохранение результатов обработки формы в лог.

Исходные коды формы обратной связи

Проект формы обратной связи находится на GitHub по этому адресу. Распространяется форма под лицензией MIT.

Для работы серверных сценариев формы необходим php не ниже версии 5.6.

Текущая версия формы 3.0.1. Данная форма имеет дизайн, выполненных с помощью стилей, собранных в файле «style.css». Скачать контактную форму можно по этой ссылке.

Другие релизы этой формы можно посмотреть на этой странице, а также на «Яндекс.Диск».

Демо формы «FeedbackForm»

Скриншоты формы обратной связи

Внешний вид формы обратной связи Как осуществляется валидация формы обратной связи Отображение информации об успешной отправки формы обратной связи

Строение формы обратной связи

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

Данная форма работает через AJAX. Любую форму обратной связи, работающую с использованием данной технологии, можно представить в виде схемы:

Принцип работы AJAX формы обратной связи

Из схемы видно, что форма обратной связи состоит из 2 основных частей: клиентской и серверной.

Клиентская часть данной формы представлена посредством следующих файлов:

  • index.html - веб-страница, содержащая html5 форму обратной связи;
  • process-forms.js - JavaScript сценарий, выполняющий всю логику по обработке формы на стороне клиента;
  • jquery.js - библиотека jQuery, необходимая для работы скриптов файла process-forms.js.

По умолчанию HTML форма, представленная в проекте, состоит из:

  • текстового поля для ввода имени;
  • текстового поля для ввода email-адреса;
  • textarea поля для ввода текста сообщения;
  • элемента input с type="file" (для добавления файлов);
  • капчи (для защита от спама);
  • чекбокса, посредством которого пользователь соглашается с условиями по обработке представленной им в форме информации;
  • кнопки, посредством которой пользователь осуществляет отправку данных формы на сервер.

Код JavaScript, находящийся в файле «process-forms.js» содержит всю логику, необходимую для обработки формы на стороне клиента.

Он выполняет:

  • проверку (валидацию) данных формы перед отправкой их на сервер; не корректные данные обводятся в красную рамку и снабжаются подсказкой; выполнение проверки текстовых полей осуществляется с использованием HTML5 функции checkValidity;
  • загрузку и отображение файлов, которые будут отправлены на сервер; изображения отображаются с превью (на основе объекта FileReader); организовано это с использованием элемента input с type="file" и установленого атрибута multiple;
  • обновление кода капчи и получения нового изображения на котором он написан;
  • отправку данных на сервер посредством метода POST без перезагрузки страницы;
  • обработку ответа от сервера и отображение его пользователю.

Серверная часть формы обратной связи состоит из:

  • captcha.php (скрипта для генерации капчи);
  • oswald.ttf (шрифта, посредством которого код капчи пишется на изображении);
  • background.png (изображения (фона), на которое накладывается текст капчи);
  • process.php (скрипта, выполняющего обработку данных формы на сервере; при их успешной проверке осуществляет отправку этих данных на email; результат своего выполнения возвращает в формате JSON);
  • файлов, находящихся в каталоге PHPMailer (php библиотеки, позволяющей более просто и безопасно отправлять электронные письма).
Серверная часть формы обратной связи

PHP скрипт process.php выполняет следующие функции:

  • проверяет метод запроса, а также как он послан (с помощью AJAX или нет);
  • выполняет очистку (фильтрацию) данных (для защиты от XSS);
  • выполняет проверку (валидацию) полей формы;
  • проверяет правильность введённого пользователем кода капчи;
  • проверяет, соответствуют ли полученные файлы установленным характеристикам;
  • перемещает файлы, отправленные пользователем, под уникальными именами в заданную директорию на сервере;
  • в случае успешного выполнения всех вышеприведённых действий отправляет письмо (email) с вложениями по указанному адресу. Кроме отправки письма он также сохраняет данные формы в текстовый файл;
  • отправляет клиенту (браузеру пользователя) результат (ответ) в формате JSON, содержащий сведения об успехе или возникшие при обработке формы ошибки.

Установка и настройка формы обратной связи

Установка формы обратной связи на сервер осуществляется путём копирования папки feedback в корневую директорию сайта.

После копирования контактная форма на сайте с доменным именем sitename.ru будет доступна адресу http://sitename.ru/feedback/ или https://sitename.ru/feedback/ в зависимости от используемого протокола.

Основные действия по настройке формы:

  1. Определиться с полями формы (файл index.html). При необходимости добавить новые поля или удалить существующие.
  2. Изменить настройки инициализации формы в файле main.js.
  3. Изменить переменные и константы в файле process.php.
  4. При изменении полей HTML формы внести коррективы в файл process.php.
  5. Поправить файл email.tpl (шаблон email письма). Если вы отправляете информационное письмо клиенту об успешной отправке сообщения, то необходимо отредактировать и файл email_client.tpl.

Указание обработчика HTML форме осуществляется с помощью атрибута action:

<form id="feedback-form" action="/feedback/process/process.php" enctype="multipart/form-data" novalidate>
  ...
</form>

Настройка файла main.js

Настройка JavaScript кода осуществляется посредством создания экземпляра объекта ProcessForm и указания ему необходимых параметров:

// selector: '#feedback-form-2' - селектор формы (по умолчанию '#feedback-form')
var form2 = new ProcessForm({
  selector: '#feedback-form-2'
});
form2.init();

Более детальная настройка JavaScript сценария для обработки той или иной формы осуществляется посредством указания дополнительных ключей:

/*
Параметры указываются в виде:
{
ключ: значение;
ключ: значение;
...
}

selector - селектор формы (по умолчанию '#feedback-form')
maxSizeFile - максимальный размер файла в мегабайтах (по умолчанию 0.5)
validFileExtensions - допустимые расширения файлов для загрузки (по умолчанию 'jpg','jpeg','bmp','gif','png') 
*/

С помощью функции-конструктора ProcessForm можно обрабатывать любое количество форм. Осуществляется это следующим образом:

// selector: '#feedback-form' (по умолчанию)
var form1 = new ProcessForm();
form1.init();
// selector: '#feedback-form-2'
var form2 = new ProcessForm({
  selector: '#feedback-form-2'
});
form2.init();
// selector: '#feedback-form-3'
var form3 = new ProcessForm({
  selector: '#feedback-form-3'
});
form3.init();

Ошибки валидации сценарий JavaScript отображает посредством выделения элемента формы красной рамкой и сообщением, расположенным под элементом формы.

Настройка серверного сценария process.php

Файл process.php содержит некоторые константы и переменные, которые настраивают алгоритм его работы:

/* 1 ЭТАП - НАСТРОЙКА ПЕРЕМЕННЫХ */
const 
  IS_CHECK_CAPTCHA = true, // проверять капчу
  IS_SEND_MAIL = true, // отправлять письмо получателю
  IS_SEND_MAIL_SENDER = false, // отправлять информационное письмо отправителю
  IS_WRITE_LOG = true, // записывать данные в лог
  IS_SEND_FILES_IN_BODY = true, // добавить ссылки на файлы в тело письма
  IS_SENS_FILES_AS_ATTACHMENTS = true, // необходимо ли прикреплять файлы к письму
  MAX_FILE_SIZE = 524288, // максимальный размер файла (в байтах)
  ALLOWED_EXTENSIONS = array('jpg', 'jpeg', 'bmp', 'gif', 'png'), // разрешённые расширения файлов
  MAIL_FROM = 'no-reply@mydomain.ru', // от какого email будет отправляться письмо
  MAIL_FROM_NAME = 'Имя_сайта', // от какого имени будет отправляться письмо
  MAIL_SUBJECT = 'Сообщение с формы обратной связи', // тема письма
  MAIL_ADDRESS = 'manager@mydomain.ru', // кому необходимо отправить письмо
  MAIL_SUBJECT_CLIENT = 'Ваше сообщение доставлено'; // настройки mail для информирования пользователя о доставке сообщения
$uploadPath = dirname(dirname(__FILE__)) . '/uploads/'; // директория для хранения загруженных файлов

Как формируется результат в process.php

Формирование результата обработки формы на стороне сервера (по умолчанию process.php) осуществляется с помощью переменной $data.

Основной результат обработки формы устанавливается посредством ключа result, который может иметь следующие значения:

  • success - успешная обработка формы на сервере.
  • error - возникла ошибка при проверке формы.

Создание сообщения, содержащей подробную информацию об ошибке осуществляется с помощью этой же переменной ($data), но имеющей в качестве ключа имя HTML элемента:

Например, формирование ошибки для поля email:

$data['email'] = 'Адрес электронной почты не корректный';

Создание сообщений для вывода в консоль браузера осуществляется с помощью ключа log:

$data['log'][] = 'Одно сообщение';
$data['log'][] = 'Ещё одно сообщение';

Как осуществляется добавление файлов в письмо

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

Код php, добавляющий в тело письма ссылки на файлы:

// добавление файлов в виде ссылок
if (IS_SEND_FILES_IN_BODY) {
  if (isset($attachments)) {
    $listFiles = '<ul>';
    foreach ($attachments as $attachment) {
      $fileHref = substr($attachment, strpos($attachment, 'feedback/uploads/'));
      $fileName = basename($fileHref);
      $listFiles .= '<li><a href="' . $startPath . $fileHref . '">' . $fileName . '</a></li>';
    }
    $listFiles .= '</ul>';
    $bodyMail = str_replace('%email.attachments%', $listFiles, $bodyMail);
  } else {
    $bodyMail = str_replace('%email.attachments%', '-', $bodyMail);
  }
}

В email шаблоне место, в которое будут вставлены ссылки, определяется плейсхолдером %email.attachments%:

Файлы:<br>
%email.attachments%

Прикрепление файлов к email письму в process.php осуществляется следующим образом:

// прикрепление файлов к письму
if (IS_SENS_FILES_AS_ATTACHMENTS) {
  if (isset($attachments)) {
    foreach ($attachments as $attachment) {
      $mail->addAttachment($attachment);
    }
  }
}

Записывание данных формы в лог

Кроме отправки формы на email, php-скрипт process.php также осуществляет добавление отправленных данных в файл.

/* 8 ЭТАП - ЗАПИСЫВАЕМ ДАННЫЕ В ЛОГ */
if ($data['result'] == 'success' && IS_WRITE_LOG) {
  try {  
    $name = isset($name) ? $name : '-';
    $email = isset($email) ? $email : '-';
    $message = isset($message) ? $message : '-';
    $output = "---------------------------------" . "\n";
    $output .= date("d-m-Y H:i:s") . "\n";
    $output .= "Имя пользователя: " . $name . "\n";
    $output .= "Адрес email: " . $email . "\n";
    $output .= "Сообщение: " . $message . "\n";
    if (isset($attachments)) {
      $output .= "Файлы: " . "\n";
      foreach ($attachments as $attachment) {
          $output .= $attachment . "\n";
      }
    }
    file_put_contents(dirname(dirname(__FILE__)) . '/logs/logs.txt', $output, FILE_APPEND | LOCK_EX);
  } catch(Exception $e) {
  }
}

Как убрать капчу из формы обратной связи

Если вам не нужна капча, то необходимо:

1. Удалить из HTML формы блок капча:

<!-- Капча -->
<div class="form-group captcha">
  <img class="img-captcha" src="/feedback/captcha/captcha.php" data-src="/feedback/captcha/captcha.php">
  <div class="btn btn-light position-relative refresh-captcha">Обновить</div>
  <div class="form-group">
    <label for="captcha" class="control-label">Код, показанный на изображении</label>
    <input type="text" name="captcha" maxlength="6" required="required" id="captcha" class="form-control captcha" placeholder="******" autocomplete="off" value="">
    <div class="invalid-feedback"></div>
  </div>
</div>

2. В php обработчике формы (process.php) установить константе IS_CHECK_CAPTCHA значение false.

Как добавить в форму новое поле

В качестве примера расммотрим как добавить в форму обратной связи необязательно поле "Телефон".

Основные шаги:

1. Добавить в HTML форму фрагмент кода (index.html):

<!-- Телефон пользователя -->
<div class="form-group">
  <label for="phone" class="control-label">Телефон</label>
  <div class="input-group">
    <div class="input-group-prepend">
      <div class="input-group-text">+7</div>
    </div>
    <input id="phone" type="tel" name="phone" class="form-control" value="(___)___-__-__" pattern="^\(?[0-9]{3}\)?(\s+)?[0-9]{3}-?[0-9]{2}-?[0-9]{2}$">
    <div class="invalid-feedback"></div>
  </div>
</div>

2. Создать маску для ввода телефона (например, на базе masked_input_1.4.1-min.js):

<script>
  // masked_input_1.4.1-min.js
  // angelwatt.com/coding/masked_input.php

  MaskedInput({
    elm: document.getElementById('phone'), // select by id
    format: '(___)___-__-__',
    separator: '()-'
  });
</script>

3. Вставить в process.php код для проверки корректности введённого пользователем номера телефона:

//валидация поля phone
if (!empty($_POST['phone'])) {
    $phone = preg_replace('/\D/', '', $_POST['phone']); //получить номер телефона (цифры) из строки
    if (!preg_match('/^(8|7)(\d{10})$/', $phone)) {
      $data['phone'] = 'Поле Телефон содержит не корректный номер!';
      $data['result'] = 'error';
    }
}

4. В process.php добавить строчку, которая будет заменять плейсхолдер %email.phone% в шаблоне письма на указанный в форме:

$bodyMail = str_replace('%email.phone%', isset($phone) ? $phone : 'не указан', $bodyMail);

5. Во фрагмент кода, который используется для записывания лога, вставить следующую строчку:

$output .= 'Телефон: ' . isset($phone) ? $phone : 'не указан' . '\n';

6. В шаблон письма (email.tpl) вставить в нужное место следующий код:

Телефон пользователя: <b>%email.phone%</b><br>

Пример формы с полем "Телефон" можно загрузить отсюда.

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

При необходимости на страницу можно добавить несколько форм обратной связи.

Осуществляется это посредством выполнения следующих шагов.

В HTML файле (index.html) нужно:

  • скопировать имеющийся фрагмент формы обратной связи и расположить его в нужном месте страницы;
  • установить форме новый идентификатор, т.е. значение атрибута id (например, feedback-form-2);
  • указать атрибуту action формы путь к php-сценарию, который будет обрабатывать её на стороне сервера (например, /feedback/process/process-2.php);
  • установить капче (элементу img) в атрибуте src и data-src get-параметр; его значение будет являться ключом, с которым будет связан её код на сервере (например, /feedback/captcha/captcha.php?id=captcha-2);
  • изменить у формы значения атрибутов id и for так, чтобы они были уникальными на странице;
  • установить ссылке с помощью которой перезапускается форма значение атрибута data-reloadform (например, #feedback-form-2).

В JavaScript файле (main.js) необходимо добавить блок инициализации для второй формы:

var form2 = new ProcessForm({
  selector: '#feedback-form-2'
});
form2.init();

Последнее действие – это выполнить создание копии файла process.php. В новом файле (например, process-2.php) необходимо изменить код, посредством которого эта форма должна будет обрабатываться на сервере.

Если в форме не изменяется количество полей, то достаточно будет изменить только фрагмент кода, в котором проверяется код капчи. А именно изменить ключ в суперглобальном массиве $_SESSION с captcha на тот, который мы установили (в данном случае на captcha-2).

Скачать готовый архив с двумя формами, расположенными на одной странице, можно по этой ссылке.


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