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

Рейтинг: 0Ответов: 1Опубликовано: 30.07.2025

В форму надо добавить отправку приложенного файла. Прошу помочь - у меня не получается.

    <form id="form48104882" name='form48104882' role="form" action='' method='POST' data-formactiontype="2" data-inputbox=".t-input-group" class="t-form js-form-proccess t-form_inputs-total_4 t-form_bbonly " data-success-callback="t718_onSuccess" > 
        <input type="hidden" name="formservices[]" value="b77669c117ccdc320fbfd833959aee7d" class="js-formaction-services"> 
        <div class="js-successbox t-form__successbox t-text t-text_md" style="display:none;background-color:#ffd014;">
            <div style="color:#000000;" data-customstyle="yes">Cпасибо! Данные успешно отправлены.</div>
        </div>
        <div class="t-form__inputsbox"> 
            <div class="t-input-group t-input-group_ph" data-input-lid="1521548014127"> 
                <div class="t-input-block"> <input type="text" name="Phone" class="t-input js-tilda-rule t-input_bbonly" value="" placeholder="Ваш номер телефона" data-tilda-req="1" data-tilda-rule="phone" style="color:#000000; border:2px solid #999999; background-color:#ffffff; "> 
                    <div class="t-input-error"></div>
                </div>
            </div>
            <div class="t-input-group t-input-group_em" data-input-lid="1496238230199"> 
                <div class="t-input-block"> 
                    <input type="text" name="Email" class="t-input js-tilda-rule t-input_bbonly" value="" placeholder="Ваш емейл" data-tilda-rule="email" style="color:#000000; border:2px solid #999999; background-color:#ffffff; "> 
                    <div class="t-input-error"></div>
                </div>
            </div>
            <div class="t-input-group t-input-group_nm" data-input-lid="1496238250184"> 
                <div class="t-input-block"> 
                    <input type="text" name="Name" class="t-input js-tilda-rule t-input_bbonly" value="" placeholder="Ваше имя" data-tilda-rule="name" style="color:#000000; border:2px solid #999999; background-color:#ffffff; "> 
                    <div class="t-input-error"></div>
                </div>
            </div>
            <div class="t-input-group t-input-group_ta" data-input-lid="1496238259342"> 
                <div class="t-input-block"> 
                    <textarea name="Textarea" class="t-input js-tilda-rule t-input_bbonly" placeholder="Ваше сообщение" style="color:#000000; border:2px solid #999999; background-color:#ffffff; height:102px" rows="3"></textarea> 
                    <div class="t-input-error"></div>
                </div>
            </div>
            
            <div class="t-form__errorbox-middle"> 
                <div class="js-errorbox-all t-form__errorbox-wrapper" style="display:none;"> 
                    <div class="t-form__errorbox-text t-text t-text_md"> 
                        <p class="t-form__errorbox-item js-rule-error js-rule-error-all"></p> 
                        <p class="t-form__errorbox-item js-rule-error js-rule-error-req"></p> 
                        <p class="t-form__errorbox-item js-rule-error js-rule-error-email"></p> 
                        <p class="t-form__errorbox-item js-rule-error js-rule-error-name"></p> 
                        <p class="t-form__errorbox-item js-rule-error js-rule-error-phone"></p> 
                        <p class="t-form__errorbox-item js-rule-error js-rule-error-string"></p> 
                    </div>
                </div>
            </div>
            <div class="t-form__submit"> 
                <button type="submit" class="t-submit" style="color:#000000;background-color:#ffd014; border:5px solid white; border-radius:30px; -moz-border-radius:30px; -webkit-border-radius:30px;">Оставить заявку</button> 
            </div>
        </div>
        <div class="t-form__errorbox-bottom"> 
            <div class="js-errorbox-all t-form__errorbox-wrapper" style="display:none;"> 
                <div class="t-form__errorbox-text t-text t-text_md"> 
                     <p class="t-form__errorbox-item js-rule-error js-rule-error-all"></p> 
                     <p class="t-form__errorbox-item js-rule-error js-rule-error-req"></p> 
                     <p class="t-form__errorbox-item js-rule-error js-rule-error-email"></p> 
                     <p class="t-form__errorbox-item js-rule-error js-rule-error-name"></p> 
                     <p class="t-form__errorbox-item js-rule-error js-rule-error-phone"></p> 
                     <p class="t-form__errorbox-item js-rule-error js-rule-error-string"></p> 
                </div>
            </div>
        </div>
    </form>

И в send.php

    if ($_POST)
{

$to_name = 'New message from the site customhelp.ru';//Отправитель

/* $to = "sales@garantp.com";//Ваш E-mail */
$to = "v.kirillova@vavbroker.ru";//Ваш E-mail


$header = "From: \"$to_name\" <no-reply@".$_SERVER['HTTP_HOST'].">\n";
$header .= "Content-type: text/plain; charset=\"utf-8\"";
$subject = "Garant Project LLC";//Тема письма


if (!isset($_POST['Phone']) || empty($_POST['Phone']))
{
 $b['phone'] = $_POST['PHONE'];
 $_POST['Phone'] = 'Телефон: '.$_POST['PHONE'];
} else {
$b['phone'] = $_POST['Phone'];
 $_POST['Phone'] = 'Телефон: '.$_POST['Phone'];
}



if (isset($_POST['Email']))
{
 $b['email'] = $_POST['Email'];
 $_POST['Email'] = 'E-Mail: '.$_POST['Email'];

} else {
 $_POST['Email'] = '';
}

if (isset($_POST['Name']))
{
 $b['name'] = $_POST['Name'];
 $_POST['Name'] = 'Имя: '.$_POST['Name'];

} else {
 $_POST['Name'] = '';
}

if (isset($_POST['Textarea']))
{
 $b['text'] = $_POST['Textarea'];
 $_POST['Textarea'] = 'Сообщение: '.$_POST['Textarea'];

} else {
 $_POST['Textarea'] = '';
}

$message = 'Информация о заявке:

'.$_POST['Phone'].'
'.$_POST['Email'].'
'.$_POST['Name'].'
'.$_POST['Textarea'].'
';

Ответы

▲ 9

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

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

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

Добавление загрузки файла в форму

Допустим у нас уже была форма

<form method="POST">
  Email: <input type="text" name="email"><br>
  Имя: <input type="text" name="name"><br>
  Текст:<br>
  <textarea name="text"></textarea><br>
  <input type="submit">
</form>

Теперь нам в неё надо добавить два элемента, указанные в документации: атрибут enctype и само поле для загрузки файла.

                    <!-- ↓↓↓ здесь ↓↓↓ -->
<form method="POST" enctype="multipart/form-data">
  Email: <input type="text" name="email"><br>
  Имя: <input type="text" name="name"><br>
  Текст:<br>
  <textarea name="text"></textarea><br>
  <input type="file" name="file"><!-- ← и здесь -->
  <input type="submit">
</form>

Получение данных из формы

После этого НАД формой (если непонятно, почему над, а не под, читаем здесь) пишем обработчик

<?php
$error = '';
$file = '';

if ($_POST) {
    # сначала надо понять, введены ли данные правильно
    # правил валидации может быть много, но мы сделаем только самую базовую
    $email = $_POST['email'] ?? '';
    $name = $_POST['name'] ?? '';
    $text = $_POST['text'] ?? '';
    if (mb_strlen($name) < 2 || mb_strlen($text) < 10) {
        $error .= "Необходимо ввести имя и текст. ";
    }
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $error .= "Необходимо ввести корректный email. ";
    }
    # мы сделаем загрузку необязательной, 
    # и будем добавлять файл, только если он был отправлен
    # если же файл обязательный, то в условии поменять проверку
    # на === и выдавать ошибку, если файл не загружен.
    if ($_FILES['file']['error'] !== UPLOAD_ERR_NO_FILE)
    {
        if ($_FILES['file']['error'] === UPLOAD_ERR_OK)
        {
            $filename = $_FILES['file']['name'];
            $file = $_FILES['file']['tmp_name'];

            # опять же, минимальная валидация
            $maxsize = 2 * 1024 * 1024; // 2Mb
            $allowed = array('doc', 'xlsx', 'pdf', 'txt');
            $ext = pathinfo($filename, PATHINFO_EXTENSION);
            if (!in_array($ext, $allowed)) {
                $error .= "Загрузить можно только файл типа ".implode(', ', $allowed). ". ";
            }
            if($_FILES['file']['size'] > $maxsize || $_FILES["file"]["size"] === 0) {
                $error .= "Размер файла не может нулевым или превышать $maxsize байт. " ;
            }
        } else {
            $error .= "Неизвестная ошибка, попробуйте позднее. ";
        }
    }
}

Таким образом, после отправки формы мы получим либо ошибку (которую выведем над формой), либо переменные $email, $name, $text и $file (плюс $filename, если файл был загружен). И теперь можем приступать к отправке.

Отправка письма с вложением

Традиционно, все руководства по отправке писем с сайта используют функцию mail(). Однако, как я писал 10 лет назад,

следует понимать, что отправка почты - это не просто копирование в свой скрипт каких-то определенных сочетаний символов, которые случайно сработали в прошлом веке у автора какой-либо допотопной статьи. Это гораздо более сложный процесс, который включает множество нюансов. И поэтому отправку почты надо не лепить вручную из подручных средств на ходу, а доверить проверенному и отлаженному решению.

Не говоря уже о том, что все меньше остаётся хостингов, где эта функция вообще работает, а если работает, то письма не попадают в спам

Поэтому вместо функции mail() мы будем использовать проверенную библиотеку PHPMailer.

Установка PHPmailer

Если вы уже знаете, что такое пространства имён, Composer и автозагрузка, то объяснять вам ничего не надо. Просто добавляете к своему проекту ещё один пакет через

composer require phpmailer/phpmailer

добавляете в скрипт строчку require __DIR__ . '/vendor/autoload.php'; и пользуетесь.

Однако, вопрос "как отправить вложение на почту" задают обычно люди и так-то весьма далёкие от программирования, а освоение каких-то новых инструментов становится для них и вовсе неодолимым препятствием. Поэтому приведем пример установки "на изоленту".

  1. В той же папке, где лежит наш скрипт, создаём папку PHPMailer.
  2. Идём в гитхаб проекта, нажимаем большую зелёную кнопку и выбираем "Скачать zip".
  3. Распаковываем архив, и из папки src копируем в свою папку PHPMailer три файла: PHPMailer.php, SMTP.php и Exception.php.
  4. Добавляем в наш скрипт код, который подключает эти три файла вручную (соответственно, при использовании Композера эти три require нужно будет удалить).

Окончательный код

Этот скрипт одновременно показывает форму и обрабатывает её. Если мы просто обратились к этому файлу через браузер (то есть запрос был сделан методом GET) то будет показана форма. А после того как она будет отправлена, запустится обработчик метода POST, который произведёт все проверки и либо отправит сообщение на почту, либо покажет ошибку и выведет форму снова.

<?php
# здесь вводите СВОЙ email, на который будете отправлять письма из формы
$mailto = "";

$error = '';
$file = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    # сначала надо понять, введены ли данные правильно
    # правил валидации может быть много, но мы сделаем только самую базовую
    $email = $_POST['email'] ?? '';
    $name = $_POST['name'] ?? '';
    $text = $_POST['text'] ?? '';
    if (mb_strlen($name) < 2 || mb_strlen($text) < 10) {
        $error .= "Необходимо ввести имя и текст. ";
    }
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $error .= "Необходимо ввести корректный email. ";
    }
    # мы сделаем загрузку необязательной, и будем добавлять файл, только если он был отправлен
    # если же файл обязательный, то надо будет проверять на равенство и выдавать ошибку
    if ($_FILES['file']['error'] !== UPLOAD_ERR_NO_FILE)
    {
        if ($_FILES['file']['error'] === UPLOAD_ERR_OK)
        {
            $filename = $_FILES['file']['name'];
            $file = $_FILES['file']['tmp_name'];

            # опять же, минимальная валидация
            $maxsize = 2 * 1024 * 1024; // 2Mb
            $allowed = array('doc', 'xlsx', 'pdf', 'txt');
            $ext = pathinfo($filename, PATHINFO_EXTENSION);
            if (!in_array($ext, $allowed)) {
                $error .= "Загрузить можно только файл типа ".implode(', ', $allowed). ". ";
            }
            if($_FILES['file']['size'] > $maxsize || $_FILES["file"]["size"] === 0) {
                $error .= "Размер файла не может нулевым или превышать $maxsize байт. " ;
            }

        } else {
            $error .= "Неизвестная ошибка, попробуйте позднее. ";
        }
    }

    # Если не было ошибок
    if ($error === '') {
        require __DIR__.'/PHPMailer/PHPMailer.php';
        require __DIR__.'/PHPMailer/Exception.php';
        require __DIR__.'/PHPMailer/SMTP.php';

        $mail = new PHPMailer\PHPMailer\PHPMailer(true);

        # Адрес, куда отправлять (свой адрес)
        $mail->addAddress($mailto);

        # Адрес, куда отвечать (введённый в форму)
        $mail->addReplyTo($email);

        # Сабжект (заголовок) письма
        $mail->Subject = 'Обратная связь с сайта';

        # Текст письма
        $mail->IsHTML(false);
        $mail->Body = "Имя: $name\nСообщение:\n$text";

        # Файл
        if ($file !== '') {
            $mail->addAttachment($file, $filename);
        }

        # Отправка
        $mail->send();       
        
        # после отправки POST запроса ВСЕГДА должен быть редирект
        # В простейшем случае можно отправить на отдельную страницу со спасибом за обратную связь
        header("Location: thanks.html");
        # после редиректа ВСЕГДА должно быть завершение работы
        die;
    }
}
?>
<?= htmlspecialchars($error); ?><br>
<form method="POST" enctype="multipart/form-data">
  Email: <input type="text" name="email"><br>
  Имя: <input type="text" name="name"><br>
  Текст:<br>
  <textarea name="text"></textarea><br>
  <input type="file" name="file"><br><!-- ← и здесь -->
  <input type="submit">
</form>

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

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

  1. Идёте на яндекс, гугль или куда угодно и создаёте email.
  2. Дальше ищете инструкцию, как включить отправку почты сторонними приложениями для соответствующего сервера. Например, для Яндекса это здесь.
  3. Сразу под строчкой $mail = new PHPMailer(true); добавляем такой блок кода:
$smtp_username = ""; // email, который вы создали
$smtp_password = ""; // пароль для отправки, который создали по инструкции выше

$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->SMTPSecure = "tls"; // из инструкции
$mail->Host = "smtp.yandex.ru"; // из инструкции
$mail->Port = 587; // из инструкции

$mail->Username = $smtp_username;
$mail->Password = $smtp_password;
$mail->setFrom($smtp_username);