Ответ
Обработка загрузки файлов — стандартная, но критичная с точки зрения безопасности задача. Мой опыт охватывает как простые формы загрузки аватаров, так и сложные системы для контента с валидацией, обработкой и загрузкой в облако.
Безопасность — это приоритет. Моя типичная реализация включает:
- Валидацию на стороне сервера: Проверку MIME-типа через
finfo_file(), а не только расширения. Ограничение размера файла. - Санацию имен: Удаление опасных символов из оригинального имени файла с помощью
preg_replace(). - Генерацию уникального имени: Использование
uniqid()или хеша от содержимого файла, чтобы избежать перезаписи и инъекций в путь. - Проверку
is_uploaded_file()иmove_uploaded_file()для предотвращения атак на файловую систему.
Пример безопасной загрузки изображения:
if ($_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
$tmpPath = $_FILES['avatar']['tmp_name'];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $tmpPath);
finfo_close($finfo);
// Разрешаем только JPEG и PNG
$allowedTypes = ['image/jpeg', 'image/png'];
if (!in_array($mimeType, $allowedTypes)) {
throw new Exception('Недопустимый тип файла.');
}
// Генерируем безопасное имя и перемещаем файл
$extension = pathinfo($_FILES['avatar']['name'], PATHINFO_EXTENSION);
$safeFileName = uniqid('avatar_') . '.' . $extension;
$targetPath = '/var/www/uploads/avatars/' . $safeFileName;
if (move_uploaded_file($tmpPath, $targetPath)) {
// Дополнительная обработка: создание превью через GD/Imagick
createThumbnail($targetPath, 150, 150);
}
}
Для проектов с высокой нагрузкой интегрировал загрузку напрямую в Amazon S3 или подобные облачные хранилища, используя их SDK, чтобы разгрузить сервер приложения.