Перейти к содержимому
CMS

Форма обратной связи на PHP с загрузкой файла: безопасная обработка

Как принять форму и файл в PHP безопаснее: multipart/form-data, лимиты размера, проверка MIME, move_uploaded_file, случайное имя и отправка письма через библиотеку.

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

Пример формы обратной связи с загрузкой файла

HTML-форма

<form method="post" enctype="multipart/form-data">
  <input type="text" name="name" required>
  <input type="email" name="email" required>
  <input type="file" name="attachment" required>
  <button type="submit">Отправить</button>
</form>

Проверяем ошибку и размер

$file = $_FILES['attachment'] ?? null;

if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
    throw new RuntimeException('Ошибка загрузки файла');
}

if ($file['size'] > 5 * 1024 * 1024) {
    throw new RuntimeException('Файл слишком большой');
}

Определяем MIME на сервере

$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file['tmp_name']);

$allowed = [
    'application/pdf' => 'pdf',
    'image/jpeg' => 'jpg',
    'image/png' => 'png',
];

if (!isset($allowed[$mime])) {
    throw new RuntimeException('Недопустимый тип файла');
}

Сохраняем под новым именем

$name = bin2hex(random_bytes(16)) . '.' . $allowed[$mime];
$target = __DIR__ . '/private_uploads/' . $name;

if (!move_uploaded_file($file['tmp_name'], $target)) {
    throw new RuntimeException('Не удалось сохранить файл');
}

move_uploaded_file() дополнительно проверяет, что исходный файл действительно пришёл через механизм HTTP POST PHP. Каталог вложений лучше держать вне публичного web-root либо запрещать в нём выполнение скриптов.

Отправка письма

Для вложений лучше использовать поддерживаемую почтовую библиотеку, например Symfony Mailer или PHPMailer, а не собирать MIME-письмо вручную через mail(). SMTP-аутентификацию и пароль храните в переменных окружения.

Что ещё обязательно

  • CSRF-защита;
  • ограничение частоты отправок;
  • серверная валидация email;
  • лимит разрешённых типов;
  • удаление временных файлов после отправки;
  • не использовать исходное имя файла как путь на сервере.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *