В 19-ом уроке мы разберем один из ключевых навыков для веб-разработчика, это работу с загрузкой файлов на сервер через PHP. Вы научитесь создавать безопасные формы, обрабатывать файлы и защищаться от распространенных уязвимостей.
Практически каждый современный сайт позволяет пользователям загружать файлы: аватарки, документы, фотографии для постов. Без этого навыка вы не сможете создать полноценный веб-проект. Но важно помнить, что неправильная реализация загрузки файлов может привести к уязвимостям! Поэтому сегодня я научу вас не только базовым техникам, но и правилам безопасности.
Настройка HTML-формы
Для загрузки файлов нужна специальная HTML-форма. Вот ключевые моменты:
- Метод отправки:
POST
(GET не подходит, так как ограничен длиной URL). - Атрибут
enctype
: Должен бытьmultipart/form-data
. Без него файлы не отправятся! - Поле для файла:
<input type="file" name="myfile">
.
Пример формы:
<form action="upload.php" method="post" enctype="multipart/form-data"> <label>Выберите файл:</label> <input type="file" name="userfile"> <input type="submit" value="Загрузить"> </form>
Обработка файлов в PHP
После отправки формы данные о файле попадают в суперглобальный массив $_FILES
. Его структура:
$_FILES['userfile'] = [ 'name' => 'photo.jpg', // Имя файла 'type' => 'image/jpeg', // MIME-тип 'tmp_name' => '/tmp/php123', // Временный путь 'error' => 0, // Код ошибки 'size' => 10240 // Размер в байтах ];
Основные шаги обработки:
- Проверить, был ли файл загружен:
if (!isset($_FILES['userfile'])) { die('Файл не был отправлен.'); }
- Обработать ошибки:
if ($_FILES['userfile']['error'] !== UPLOAD_ERR_OK) { switch ($_FILES['userfile']['error']) { case UPLOAD_ERR_INI_SIZE: die('Файл слишком большой.'); // ... другие коды ошибок } }
- Проверить тип и размер файла:
$allowedTypes = ['image/jpeg', 'image/png']; $maxSize = 2 * 1024 * 1024; // 2 МБ if (!in_array($_FILES['userfile']['type'], $allowedTypes)) { die('Недопустимый тип файла.'); } if ($_FILES['userfile']['size'] > $maxSize) { die('Файл превышает допустимый размер.'); }
- Переместить файл в постоянную директорию:
$uploadDir = __DIR__ . '/uploads/'; $filename = uniqid() . '_' . basename($_FILES['userfile']['name']); // Защита от перезаписи if (!move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadDir . $filename)) { die('Ошибка при сохранении файла.'); } echo 'Файл успешно загружен!';
Безопасность это важно!
- Переименовывайте файлы: Используйте
uniqid()
или хеши, чтобы избежать перезаписи. - Ограничивайте типы файлов: Не доверяйте MIME-типу из
$_FILES
— проверяйте реальный тип черезfinfo_file()
. - Устанавливайте лимит размера: Настройте
upload_max_filesize
вphp.ini
.
Пример проверки реального MIME-типа:
$finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($_FILES['userfile']['tmp_name']); if (!in_array($mime, $allowedTypes)) { die('Обнаружен поддельный MIME-тип!'); }
Практические задачи
Задача 1: Загрузка аватара
Создайте форму для загрузки аватара пользователя. Требования:
- Только JPEG/PNG.
- Максимум 1 МБ.
- Автоматическое переименование файла.
Решение:
// Код обработчика upload.php if ($_SERVER['REQUEST_METHOD'] === 'POST') { $allowed = ['image/jpeg', 'image/png']; $maxSize = 1024 * 1024; if (!in_array($_FILES['avatar']['type'], $allowed) || $_FILES['avatar']['size'] > $maxSize) { die('Недопустимый файл.'); } $newName = 'avatar_' . uniqid() . '.jpg'; move_uploaded_file($_FILES['avatar']['tmp_name'], __DIR__ . '/uploads/' . $newName); }
Задача 2: Множественная загрузка
Доработайте форму, чтобы можно было загружать до 5 файлов одновременно.
Подсказка:
<input type="file" name="files[]" multiple>
Обработка в PHP:
foreach ($_FILES['files']['tmp_name'] as $key => $tmpName) { // Проверяем каждый файл }
Теперь вы умеете работать с загрузкой файлов, это важный шаг в вашем обучении. Чтобы закрепить знания, попробуйте создать галерею изображений с возможностью предпросмотра.
Полный курс по PHP для начинающих, освойте веб-разработку с нуля!