Форма обратной связи на PHP

8:51 13.07.2017
Давно не писал что ни будь на PHP, вот решил напомнить о себе! Буду писать форму обратной связи. Форма обратной связи есть практически на каждом сайте, служит она для связи с администрацией сайта, для каких то вопросов или предложений.

Давайте прежде разберемся, что именно делает сценарий обратной связи: он принимает и проверяет введенные пользователем данные, если все данные верны, отправляет их на указанную почту, на почту администратора. Какие данные должен ввести пользователь? Обычно это его имя - чтобы знать, как можно обратиться к человеку, электронную почту - чтобы знать куда отправлять ответное письмо и текст письма - где будет содержаться суть обращения. Получается всего три поля для заполнения, и этого вполне достаточно, но полей может быть гораздо больше, например, может быть поле для заголовка письма, для номера телефона, для выбора получателя в виде выпадающего списка (например: администрация | техническая поддержка | отдел рекламы), для ввода символов с картинки - чтобы убедиться, что пишет человек, а не спам бот, и так далее.

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

Все о чем я рассказал выше, мы с Вами будем делать в этой теме, но для начала давайте напишем самый простой сценарий формы обратной формы. Я писал HTML форму с тремя полями: имя отправителя, электронная почта и текст сообщения. Выглядит она так:
<form action="" method="POST">
    <table>
        <tr>
            <td>Ваше имя:</td>
            <td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>Эл. почта:</td>
            <td><input type="text" name="mail"></td>
        </tr>
        <tr>
            <td>Сообщение:</td>
            <td><textarea rows="8" cols="35" name="message"></textarea></td>
        </tr>
        <tr>
            <td><input type="submit" name="submit" value="Отправить"></td>
            <td></td>
        </tr>
    </table>
</form> 

Теперь необходимо написать сценарий для приема введенных данных и отправки их. Я сделал так:
if (isset($_POST['submit'])) # Проверка: была ли нажата кнопка
{
    $recipient = '';                                      # Адрес получателя
    $subject   = 'Обращение через форму обратной связи';  # Заголовок письма
    $header    = 'Content-type:text/html; charset=utf-8'; # Кодировка письма
    # Тело письма
    $message   = 'Получено письмо от: <strong>' . $_POST['name'] . '</strong> Обратный адрес: ' . $_POST['mail'] . '
        <br /><br />Текст письма:<br />*** *** *** *** ***<br /><br />' . $_POST['message'] . '<br /><br />*** *** *** *** ***';

    mail($recipient, $subject, $message, $header); # Отправка письма
    echo 'Сообщение успешно отправлено!';
}

Тут необходимо заполнить переменную $recipient своим электронным ящиком.
Данный сценарий не проверяет корректность введенных данных и у него нет обязательных полей, то есть сообщение будет отправлено в любом случаи, что не правильно. Но скоро мы с Вами это исправим и все будет, как положено!
8:51 13.07.2017
Давайте продолжим писать наш скрипт обратной связи. Сейчас мы сделаем поля обязательными, то есть если пользователь не заполнит, какое то из полей, то получит сообщение о необходимости всех данных. Проверять заполнено ли поле мы будем при помощи функции empty(). Я переписал сценарий, который представлен выше так:
if (isset($_POST['submit']))
{
    if (empty($_POST['name']))
    {
        echo 'Необходимо указать своё имя.';
    }
    else if (empty($_POST['mail']))
    {
        echo 'Необходимо указать свою электронную почту.';
    }
    else if (empty($_POST['message']))
    {
        echo 'Необходимо текст сообщения.'; 
    }
    else
    {
        $recipient = '';                                      # Адрес получателя
        $subject   = 'Обращение через форму обратной связи';  # Заголовок письма
        $header    = 'Content-type:text/html; charset=utf-8'; # Кодировка письма
        # Тело письма
        $message   = 'Получено письмо от: <strong>' . $_POST['name'] . '</strong> Обратный адрес: ' . $_POST['mail'] . '
            <br /><br />Текст письма:<br />*** *** *** *** ***<br /><br />' . $_POST['message'] . '<br /><br />*** *** *** *** ***';

        mail($recipient, $subject, $message, $header);
        echo 'Сообщение успешно отправлено!';
    }
}

HTML форма остается без изменений. Теперь прежде, чем письмо будет, все данные будут проверенны на их наличие. Если все данные введены, то сценарий отправит письмо на адрес администратора. Однако наша работа не закончена.
8:53 13.07.2017
Продолжаем допиливать скрипт обратной связи, и сейчас мы сделаем проверку на количество символов, для поля имени отправителя и текста сообщения. Если количество введенных символов будет меньше указанного, то пользователь получит соответствующее сообщение. Для электронной почты отправителя сделаем проверку на корректность. Если пользователь ошибется при вводе свой почты, то так же получит ошибку с неверными данными, то есть почтой.
Для имени отправителя я сделал минимальное количество символов три, для текста сообщения десять, их с легкостью можно изменить.
Значит делаем так: после:
    if (empty($_POST['name']))
    {
        echo 'Необходимо указать своё имя.';
    } 

Добавляем:
    else if (mb_strlen($_POST['name']) < 3)
    {
        echo 'Вы ввели слишком короткий имя. Минимум 3 символа.';
    } 

Чтобы изменить минимальное количество символов, измените цифру 3 на необходимое число.

Дальше после:
    else if (empty($_POST['mail']))
    {
        echo 'Необходимо указать свою электронную почту.';
    } 

Добавляем:
    else if (!preg_match('/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/', $_POST['mail']))
    {
        echo 'Неправильно введен адрес электронной почты';
    } 

И после:
    else if (empty($_POST['message']))
    {
        echo 'Необходимо текст сообщения.'; 
    } 

Добавляем:
    else if (mb_strlen($_POST['message']) < 10)
    {
        echo 'Вы ввели слишком короткое сообщение. Минимум 12 символов.';
    } 

Чтобы изменить минимальное количество символов, измените цифру 10 на необходимое число.

В итоге должно получиться:
if (isset($_POST['submit']))
{
    if (empty($_POST['name']))
    {
        echo 'Необходимо указать своё имя.';
    }
    else if (mb_strlen($_POST['name']) < 3)
    {
        echo 'Вы ввели слишком короткий имя. Минимум 3 символа.';
    }
    else if (empty($_POST['mail']))
    {
        echo 'Необходимо указать свою электронную почту.';
    }
    else if (!preg_match('/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/', $_POST['mail']))
    {
        echo 'Неправильно введен адрес электронной почты';
    }
    else if (empty($_POST['message']))
    {
        echo 'Необходимо текст сообщения.'; 
    }
    else if (mb_strlen($_POST['message']) < 10)
    {
        echo 'Вы ввели слишком короткое сообщение. Минимум 12 символов.';
    }
    else
    {
        $recipient = '';                                      # Адрес получателя
        $subject   = 'Обращение через форму обратной связи';  # Заголовок письма
        $header    = 'Content-type:text/html; charset=utf-8'; # Кодировка письма
        # Тело письма
        $message   = 'Получено письмо от: <strong>' . $_POST['name'] . '</strong> Обратный адрес: ' . $_POST['mail'] . '
            <br /><br />Текст письма:<br />*** *** *** *** ***<br /><br />' . $_POST['message'] . '<br /><br />*** *** *** *** ***';

        mail($recipient, $subject, $message, $header);
        echo 'Сообщение успешно отправлено!';
    }
}

HTML форма без изменений.
8:54 13.07.2017
На данный момент сценарий обратной связи написан так, что он выводит ошибки допущенные пользователем по одной, то есть если пользователь не заполнит два поля, то сообщение ошибки скажет ему о необходимости заполнить только первое незаполненное поле, а остальные можно подумать заполнять не надо. Хочу это исправить и выводить сразу все допущенные пользователем ошибки, то есть про каждое поле.
Значит меняем эту часть кода:
if (isset($_POST['submit']))
{
    if (empty($_POST['name']))
    {
        echo 'Необходимо указать своё имя.';
    }
    else if (mb_strlen($_POST['name']) < 3)
    {
        echo 'Вы ввели слишком короткий имя. Минимум 3 символа.';
    }
    else if (empty($_POST['mail']))
    {
        echo 'Необходимо указать свою электронную почту.';
    }
    else if (!preg_match('/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/', $_POST['mail']))
    {
        echo 'Неправильно введен адрес электронной почты';
    }
    else if (empty($_POST['message']))
    {
        echo 'Необходимо текст сообщения.'; 
    }
    else if (mb_strlen($_POST['message']) < 10)
    {
        echo 'Вы ввели слишком короткое сообщение. Минимум 12 символов.';
    }
    else

На эту:
$error  = null;
$submit = isset($_POST['submit']) ? true : false;
if ($submit)
{
    if (empty($_POST['name']))
    {
        $error .= '<div>Необходимо указать своё имя.</div>';
    }
    else if (mb_strlen($_POST['name']) < 3)
    {
        $error .= '<div>Вы ввели слишком короткий имя. Минимум 3 символа.</div>';
    }

    if (empty($_POST['mail']))
    {
        $error .= '<div>Необходимо указать свою электронную почту.</div>';
    }
    else if (!preg_match('/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/', $_POST['mail']))
    {
        $error .= '<div>Неправильно введен адрес электронной почты.</div>';
    }

    if (empty($_POST['message']))
    {
        $error .= '<div>Необходимо текст сообщения.</div>'; 
    }
    else if (mb_strlen($_POST['message']) < 10)
    {
        $error .= '<div>Вы ввели слишком короткое сообщение. Минимум 12 символов.</div>';
    }

    if (!$error)

Над самой формой, необходимо добавить вывод ошибок:
<?php echo $error; ?>

В итоге получается сценарий такой:
<?php
$error  = null;
$submit = isset($_POST['submit']) ? true : false;
if ($submit)
{
    if (empty($_POST['name']))
    {
        $error .= '<div>Необходимо указать своё имя.</div>';
    }
    else if (mb_strlen($_POST['name']) < 3)
    {
        $error .= '<div>Вы ввели слишком короткий имя. Минимум 3 символа.</div>';
    }

    if (empty($_POST['mail']))
    {
        $error .= '<div>Необходимо указать свою электронную почту.</div>';
    }
    else if (!preg_match('/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/', $_POST['mail']))
    {
        $error .= '<div>Неправильно введен адрес электронной почты.</div>';
    }

    if (empty($_POST['message']))
    {
        $error .= '<div>Необходимо текст сообщения.</div>'; 
    }
    else if (mb_strlen($_POST['message']) < 10)
    {
        $error .= '<div>Вы ввели слишком короткое сообщение. Минимум 12 символов.</div>';
    }

    if (!$error)
    {
        $recipient = '';                                      # Адрес получателя
        $subject   = 'Обращение через форму обратной связи';  # Заголовок письма
        $header    = 'Content-type:text/html; charset=utf-8'; # Кодировка письма
        # Тело письма
        $message   = 'Получено письмо от: <strong>' . $_POST['name'] . '</strong> Обратный адрес: ' . $_POST['mail'] . '
            <br /><br />Текст письма:<br />*** *** *** *** ***<br /><br />' . $_POST['message'] . '<br /><br />*** *** *** *** ***';

        mail($recipient, $subject, $message, $header);
        echo 'Сообщение успешно отправлено!';
    }
} 

Форма такой:
<?php echo $error; ?>
<form action="" method="POST">
    <table>
        <tr>
            <td>Ваше имя:</td>
            <td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>Эл. почта:</td>
            <td><input type="text" name="mail"></td>
        </tr>
        <tr>
            <td>Сообщение:</td>
            <td><textarea rows="8" cols="35" name="message"></textarea></td>
        </tr>
        <tr>
            <td><input type="submit" name="submit" value="Отправить"></td>
            <td></td>
        </tr>
    </table>
</form>