PHP: Разработка микрофреймворка
Теория: Файлы
Загрузка файлов в PHP
В PHP для загрузки файлов не нужны внешние библиотеки. Достаточно правильно настроить форму и обработчик.
Что нужно в HTML-форме
Чтобы браузер отправлял файл, в форме должны быть:
enctype="multipart/form-data".- Поле
<input type="file">.
Без multipart/form-data файл на сервер не придет как бинарные данные.
Где лежат загруженные файлы
После отправки данные о файле попадают в $_FILES. Важно понимать, что это не сам файл, а метаданные:
- Исходное имя.
- MIME-тип.
- Временный путь на сервере.
- Код ошибки.
- Размер.
Файл сначала сохраняется во временную директорию. Потом его нужно явно переместить в постоянное место хранения.
Почему структура $_FILES неудобная
У $_FILES специфичная структура: на верхнем уровне идут ключи name, type, tmp_name, error, size, а уже внутри - имена полей формы.
Из-за этого в реальных проектах часто используют обертки фреймворка, где работа с файлами дается через более понятный интерфейс.
Базовая схема обработки
Типичная последовательность в обработчике такая:
- Проверить, что поле файла действительно пришло.
- Прочитать код ошибки из
$_FILES. - Обработать сценарий
UPLOAD_ERR_NO_FILE, если файл необязательный. - При
UPLOAD_ERR_OKпереместить файл из временной директории. - При другой ошибке показать пользователю понятное сообщение и записать детали в лог.
Код ошибки нельзя показывать пользователю как есть. Лучше сопоставлять его с читаемым текстом.
Перемещение файла
Для сохранения используйте move_uploaded_file($tmpPath, $newPath).
Эта функция дополнительно проверяет, что файл действительно был загружен через HTTP POST. Это защита от части атак при подмене пути.
Если move_uploaded_file() вернула false, это серверная проблема, которую обязательно нужно логировать.
Именование файлов и безопасность
Не сохраняйте файл под исходным именем пользователя.
Риски:
- Возможны пробелы, Unicode-символы и другие проблемные символы.
- Возможны совпадения имен и перезапись чужого файла.
- Возможны проблемы валидации и безопасности.
Надежнее использовать:
- Уникальное имя (например, через хеш или UUID).
- Путь, связанный с идентификатором записи в БД.
Оригинальное имя при необходимости храните отдельным полем в базе.
Согласованность с базой данных
Если вы пишете запись в БД и файл на диск, важно не получить частичное сохранение.
Пример плохого сценария:
- Запись в БД добавлена.
- Сохранение файла завершилось ошибкой.
В результате в базе остается ссылка на несуществующий файл. Для надежной схемы используют транзакции и фиксируют изменения только после успешного переноса файла.
Итог
При работе с загрузкой файлов достаточно помнить базовый набор правил:
- Отправлять форму с
multipart/form-data. - Читать метаданные файла из
$_FILES. - Проверять код загрузки и обрабатывать ошибки.
- Сохранять файл через
move_uploaded_file(). - Не использовать исходное имя файла как итоговый путь.

