Обновление от 18.09.2015: изменён исходный код примера — теперь не нужно перезагружать страницу даже если через форму отправляется файл.

Это небольшой урок, в котором мы будем делать форму обратной связи. После того, как пользователь заполнит необходимые поля, введённые данные будут отправляться на сервер посредством AJAX-запроса. Если данные невалидные (например, отсутствуют обязательные для заполнения поля), то соответствующее сообщение будет показано пользователю.

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

Я знаю, что в Интернете огромное множество готовых решений, в том числе с очень красивыми формами. Более того, значительная часть этого кода была «подсмотрена» у других. Главная цель написания статьи — систематизировать собственные знания о функции отправки почты в PHP-скрипте. Если кому-то моя заметка пригодится и сэкономит время, то я буду очень рад.

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

Кстати, для тестирования отправки почты на локалхосте незаменимой станет почтовая заглушка. Поэтому рекомендую посмотреть статью «Почта на локальном сервере — установка почтовой заглушки».

Я разделил код на два файла: файл с формой и файл обработчик/отправитель письма. Конечно, можно всё собрать в один файл, но для образовательных целей лучше полностью разделить PHP и HTML код для наглядности.

Это наша форма:

Одной её уже достаточно, чтобы принять и отправить сообщение на сервер. Я не буду останавливаться на описании полей — т.к. это совсем просто.

В первой строке:

<form method=»post» action=»mails_sender.php» id=»feedback» name=»feedback» enctype=»multipart/form-data»>

mails_sender.php — означает имя файла, которому отправляются данные из формы для обработки.

enctype=»multipart/form-data» — выбран этот метод кодирования данных, поскольку к форме может быть присоединён файл.

id=»feedback» name=»feedback» задано и имя и айди для AJAX.

Данная форма вполне работоспособна и может выполнять свои функции. Использование AJAX позволяет отправлять на сервер запросы без перезагрузки страницы. Это здорово улучшает юзабилити, нравится пользователям, ведь в случае ошибки им не нужно заново вводить все данные — достаточно только исправить ошибку.

Этой строкой мы подключаем JQuery, эта библиотека на порядок облегчает AJAX-запросы, да и другие действия, для которых можно использовать «чистый» JavaScript:

<script src=»//code.jquery.com/jquery-2.1.4.min.js»></script>

Ещё две новых строки:

Первая строка представляет собой div элемент, для которого задан стиль (красный цвет), но в котором ничего нет, т. е. при загрузке формы он невидим. В него мы будем записывать ответы, полученные от сервера.

Вторая строка — это гифка «ожидание». При загрузке формы для неё задан стиль невидимости.

Код JavaScript/JQuery довольно объёмный, но больше половина строк в нём — это комментарии. Я не буду переписывать здесь содержимое комментариев, посмотрите сами — на мой взгляд, довольно доступно.

Наш JavaScript/JQuery (form.htm) у нас получился таким:

Второй файл называется mails_sender.php и содержание у него следующее:



В нём также много комментариев и, на мой взгляд, код достаточно простой для понимания.

Разве что можно сделать несколько ремарок по поводу блока:

Про использование фильтров валидации и очистки данных я рекомендую посмотреть официальную справку от PHP. Фильтр filter_input(INPUT_POST, ‘имя_элемента_формы’, FILTER_VALIDATE_EMAIL) валидирует почтовый адрес. Если адрес электронной почты неверен, то возвращается пустая строка.

Для сообщения мы дополнительно используем фильтр тэгов с помощью функции strip_tags. При этом в кавычках мы перечисляем разрешённые тэги. Если мы хотим, чтобы были отброшены все тэги и все специальные символы, то мы можем использовать filter_input(INPUT_POST, ‘имя_элемента_формы’, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); в результате чего удаляются все тэги, удаляются и кодируются специальные символы.

Но если мы хотим, чтобы некоторые тэги передавались (актуально для HTML-писем с разметкой), то мы используем более мягкий фильтр FILTER_SANITIZE_MAGIC_QUOTES, который эквивалентен функции addslashes(). Применением этого фильтра мы защищаемся от SQL-инжектов. Мы фильтруем остальные тэги для защиты от XSS-атак.

Предотвращения спама из формы обратной связи

Форма обратной связи выгодно отличается от формы добавления комментариев тем, что она не интересна «ссылочным» спамерам, которые пишут комментарий только для того, чтобы разместить свою ссылку.

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

Форма обратной связи может стать объектом «шутки» когда через неё присылается большое количество сообщений (иногда бессмысленных). Нормальные люди при этом не используют форму для отправки (нормальным людям это просто лень), а пишут скрипт/программу, которая напрямую отправляет обработчику сообщения. В качестве простого фильтра можно использовать отсев запросов, в заголовках которых отсутствует должный реферер или присутствует нестандартный пользовательский клиент. К сожалению, эти данные легко подменить, поэтому дополнительно для предотвращения этого, можно в форму добавить скрытое поле. На сервере, при получении сообщения, проверять, присутствует ли значение этого скрытого поля. Если нет — сообщение можно смело игнорировать и не беспокоить им админа.

Для простых случаев достаточно статичного скрытого поля. Если же вам «шутники» досаждают слишком много, то это поле можно сделать переменным. Например, в это поле можно записывать хеш от сегодняшнего числа + какой-нибудь соли. Т.е. скрытое поле будет «протухать» в течение дня, чтобы злоумышленник опять мог отправлять сообщения, ему нужно будет зайти на ваш сайт, чтобы увидеть новое значение скрытого поля.

Токен (метку) скрытого поля можно устанавливать и одноразовые. Главное, не делайте слишком короткое время «протухания» токена. Многие валидные пользователи пишут сообщение долго и если пользователь старался, два часа писал умное длинное сообщение, а оно не было принято сервером из-за каких-то фобий админа, то после этого пользователь может быстро написать короткое и обидное сообщение. 🙂

Если всё вышеназванное не помогает, то можно ввести ограничение на максимальное число отправленных сообщений с одного IP за определённый промежуток времени. Ну и опять можно вспомнить про капчу как про крайний вариант.

Если у вас есть своё видение по этому вопросу (а вариантов здесь множество), то буду рад увидеть ваше мнение в комментариях.


Спонсор публикаций Cyber-512

Готовим специалиста в области ИБ  - Воспитаем специалиста в области ИБ с нуля до начального уровня. После обучения сможете оказывать услуги по проведению тестирования на проникновение ( легальный хакинг )

Похожие темы

Как получить короткий и красивый e-mail... xxx: Считаешь себя креативным? Попробуй завести почту, не используя цифры. (шутка с bash.im) В бесплатных почтовых сервисах очень тяжело выбрать e-m...
Как скрыть все ошибки PHP с помощью .htaccess... Источники: https://perishablepress.com/advanced-php-error-handling-via-htaccess/ и https://perishablepress.com/how-to-enable-php-error-logging-via-h...
mysql_connect() и PHP 7 Большинство веб-сайтов в своей работе использует базы данных для хранения информации. Для сайтов, написанных на PHP, обычной является связка PHP + M...
15 маст хэв jQuery-сниппетов, которые взбодрят ваш... Честно говоря, кодинг на JavaScript может быть настоящим геморроем, причём постоянным. Тем не менее, на заре jQuery весь этот ужас остался в пр...
Новости софта от 23 августа 2014 года (PHP, CKEdit... Буквально вчера обновились две линейки PHP. Новые версии имеют номера PHP 5.5.16 и PHP 5.4.32. Списки изменений доступны здесь и здесь. Скачать свеж...