Необходимо добавить в форму обратной связи на сайте отправку файла
В форму надо добавить отправку приложенного файла. Прошу помочь - у меня не получается.
<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 = "[email protected]";//Ваш E-mail */
$to = "[email protected]";//Ваш 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'].'
';
Ответы (1 шт):
Сначала я хотел посетовать на то, что что здесь не один вопрос, а два: Как загрузить файл на сервер и как отправить файл на почту. Но в процессе написания ответа пришел к несколько противоположным выводам:
- вопросов тут куда больше: как обрабатывать форму, как отправлять почту, как устроен РНР скрипт в целом...
- значительная часть существующих ответов на все эти вопросы, и даже моих собственных знаний сильно устарела, что не позволяет получить рабочий код.
- сама по себе отправка файла в форме обратной связи представляет собой довольно распространённую задачу, которая заслуживает комплексного ответа
(по-хорошему, там ещё должны быть основы пользовательского интерфейса и проектирования веб-приложений. Но если добавить ещё и это, то сам пример отправки раздуется до совершенно безбожных размеров, поэтому всё, не относящееся напрямую к получению и отправке, представлено в минимальном виде).
Добавление загрузки файла в форму
Допустим у нас уже была форма
<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'; и пользуетесь.
Однако, вопрос "как отправить вложение на почту" задают обычно люди и так-то весьма далёкие от программирования, а освоение каких-то новых инструментов становится для них и вовсе неодолимым препятствием. Поэтому приведем пример установки "на изоленту".
- В той же папке, где лежит наш скрипт, создаём папку PHPMailer.
- Идём в гитхаб проекта, нажимаем большую зелёную кнопку и выбираем "Скачать zip".
- Распаковываем архив, и из папки src копируем в свою папку PHPMailer три файла:
PHPMailer.php,SMTP.phpиException.php. - Добавляем в наш скрипт код, который подключает эти три файла вручную (соответственно, при использовании Композера эти три 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, к примеру, вообще никогда не был доступен. В этом случае для отправки стоит использовать существующую учётную запись на каком-либо почтовом сервисе.
- Идёте на яндекс, гугль или куда угодно и создаёте email.
- Дальше ищете инструкцию, как включить отправку почты сторонними приложениями для соответствующего сервера. Например, для Яндекса это здесь.
- Сразу под строчкой
$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);