Форма обратной связи в два шага и без использования плагинов. С антиспамом само собой.

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

Шаг 1. Страница с формой

Создаём в папке с темой новый файл — это будет шаблон страницы с формой. Файл можно назвать как угодно, нам важно лишь его содержимое.

<?php
/* 
 * Template name: Форма обратной связи
 */
get_header(); // эта строчка кода у вас может отличаться
 
/*
 * Тут мы будем обрабатывать ошибки и выводить соответствующие сообщения
 */
if( isset( $_GET['msg'] ) ) {
	// в случае успеха
	if( $_GET['msg'] == 'success' )
		echo '<span>Сообщение успешно отправлено</span>';
 
	// в случае ошибки
	if( $_GET['msg'] == 'error' )
		echo '<span><strong>Ошибка:<strong> Проверьте правильность введённых вами данных.</span>';
	// вы сами можете добавить различные другие сообщения об ошибках
 
}
 
/* 
 * Антиспам-трюк
 * у нас есть два фейковых поля, при заполнении которых прерывается выполнение скрипта
 * сделаем так, чтобы они были скрыты для пользователей при помощи CSS
 */
echo '<style>textarea[name="comment"],textarea[name="message"]{display:none}</style>';
?>
	<form action="<?php echo site_url() ?>/send.php" method="POST">
		<input type="text" name="name" required="true" placeholder="Имя *" />
		<input type="text" name="email" required="true" placeholder="Email *" />
		<textarea name="comment"></textarea>
		<textarea name="message"></textarea>
		<textarea name="soobschenie" required="true" placeholder="Сообщение *"></textarea>
		<button>Отправить</button>
	</form>
<?php
get_footer();  // эта строчка кода у вас может отличаться

Шаг 2. Файл-обработчик. Отправка формы

В этой статье в качестве файла-обработчика я создал новый файл send.php прямо в директории установки WordPress, но вы можете поместить его и в тему без проблем.

<?php
// проверка на спам - просто прерываем выполнение кода, при желании можно и сообщение спамерам вывести
if( isset( $_POST['comment'] ) || isset( $_POST['message'] ) )
	exit;
 
// подключаем WP, можно конечно обойтись без этого, но зачем?
require( dirname(__FILE__) . '/wp-load.php');
 
// следующий шаг - проверка на обязательные поля, у нас это емайл, имя и сообщение
if( isset( $_POST['name'] )
  && isset( $_POST['email'] ) && is_email( $_POST['email'] ) // is_email() - встроенная функция WP для проверки корректности емайлов
  && isset( $_POST['soobschenie'] ) ) {
 
	$headers = array(
		"Content-type: text/html; charset=utf-8",
		"From: " . $_POST['name'] . " <" . $_POST['email'] . ">"
	);
 
	if( wp_mail( get_option('admin_email'), 'Сообщение с сайта', wpautop( $_POST['soobschenie'] ), $headers ) ) {
		header('Location:' . site_url('/contact?msg=success') );
		exit;
	}
 
 
}
 
header('Location:' . site_url('/contact?msg=error') );
exit;

Миша

Недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

Сам же я впервые познакомился с WordPress в 2009 году. Организатор WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда сделаем вам всё на лучшем уровне.

Комментарии — 20

Комментирование этого поста более не доступно.
  • Илья Волков 22 мая 2016 #

    будем тестить)
    хочу попробовать законектить форму к popUP окну на ccs3.

  • Илья Волков 22 мая 2016 #

    Я пытаюсь все это реализовать пока на локальном сервере. Не на выделенной странице, а в footer.php. Но при отправке почему то перекидывает на site.ru/send.php, где просто белый монитор.

    • trionikl 1 апреля 2020 #

      Тоже белый экран без всего - почему не работает?

      • Миша 1 апреля 2020 #

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

  • Илья Волков 22 мая 2016 #

    а если надо, чтобы при отправке форма приходила на 2 емайла, один из которых не админский?

    • Миша 22 мая 2016 #

      Можно емайлы в виде массива в первый аргумент функции wp_mail() передать.

      • Дмитрий 20 октября 2016 #

        А можно ли в wp_mail() подгрузить второй email из метаполя ?

        • Миша 22 октября 2016 #

          Конечно

          • Дмитрий 22 октября 2016 #

            А если форма сделана с использованием обычного обработчика на php с mail() без функции WP wp_mail() ?

            • Миша 24 октября 2016 #

              Нужно тогда поключить среду WordPress строчкой кода:

              require_once( 'wp-load.php' ); // разумеется путь будет зависеть от того, где лежит обработчик
              • Дмитрий 4 января 2017 #

                Среду WP подключил так:

                require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );

                присвоил переменной $mail2 (2й адрес) значение метаполя из поста:

                $mail_2 = get_post_meta( $post->ID, 'rr_email', true );

                В wp_mail для $to вписал массив: array(mail_1@mail.ru', $mail_2 );

                Но на 2й адрес из метаполя письмо не уходит, на 1й уходит.

                Подскажите пожалуйста, где я ошибся?

                • Миша 7 января 2017 #

                  Думаю, что $mail_2 - пустая переменная по той простой причине, что $post->ID не существует.

                  Глобальная переменная $post не задается сразу непосредственно при подключении среды WordPress.

                  Если делаете это в форме, то рекомендую ID поста передавать через hidden-поле.

                  • Дмитрий 7 января 2017 #

                    Спасибо за подсказку.
                    Получилось передать сразу нужный meta_key через value в hidden input.

  • Алексей 15 февраля 2017 #

    Здравствуйте!
    Такой вопрос - если проверку в файле обработки заменить на такую:
    if ($_POST['comment'] != '' || $_POST['message'] != '' ) {
    exit;
    }
    Будет тот же эффект по идее или нет?
    Дело в том, что формы на сайте работают на ajax и все поля записываются в строку и отправляются скриптом в файл обработки. В том числе и скрытое текстовое поле, которое люди видеть и заполнять не должны. И в итоге обработка возвращает ошибку, даже если не заполнять поле.

    • Миша 15 февраля 2017 #

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

      Да, эффект будет примерно тот же.

  • Александр 2 ноября 2019 #

    Михаил, спасибо большое за контент)!
    Подскажите, пожалуйста, я не совсем понял, как проверка на "comment" и "message"
    if( isset( $_POST['comment'] ) || isset( $_POST['message'] ) )
    защищает от спама ?
    Спасибо)!

    • Александр 2 ноября 2019 #

      Сорри, не посмотрел саму форму...

  • trionikl 1 апреля 2020 #

    не работает всё равно этот код

    • Миша 1 апреля 2020 #

      у меня работает, что бы это могло значить, хммм...