В этой статье рассмотрим форму обратной связи для сайта, спроектированную с использованием PHP, Bootstrap и jQuery.

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

Форма обратной связи (feedback form) - это одно из средств, с помощью которого можно вести диалог с пользователями сайта. Обычно её используют для сбора отзывов, идей, различных предложений или любой другой информации.

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

Основные характеристики формы

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

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

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

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

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

Текущая версия формы 2.0.2. Данная форма имеет дизайн, выполненный на базе фреймворка Bootstrap 4. Загрузить форму обратной связи можно по этой ссылке.

Если интересует форма с дизайном Bootstrap 3, то её архив можно скачать отсюда.

Другие варианты этой формы, расположены в этом каталоге.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

А именно, он используется:

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

Сбор данных с формы, подлежащих отправки на сервер выполняется в этом проекте с помощью HTML5 FormData.

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

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

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

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

Файлы формы обратной связи имеют кодировку UTF-8 без BOM.

Для проверки работоспособности формы в Денвере необходимо в корне сайта создать файл .htaccess и добавить в него строчку: AddDefaultCharset UTF-8.

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

Установка формы обратной связи на сервер осуществляется путём копирования папки 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%

Если вам данная возможность не нужна, то установите константе IS_SEND_FILES_IN_BODY значение false.

Прикрепление файлов к 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).

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


Статьи, похожие на данную тему: