Какой у вас опыт обработки загрузки файлов в PHP?

«Какой у вас опыт обработки загрузки файлов в PHP?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Обработка загрузки файлов — стандартная, но критичная с точки зрения безопасности задача. Мой опыт охватывает как простые формы загрузки аватаров, так и сложные системы для контента с валидацией, обработкой и загрузкой в облако.

Безопасность — это приоритет. Моя типичная реализация включает:

  1. Валидацию на стороне сервера: Проверку MIME-типа через finfo_file(), а не только расширения. Ограничение размера файла.
  2. Санацию имен: Удаление опасных символов из оригинального имени файла с помощью preg_replace().
  3. Генерацию уникального имени: Использование uniqid() или хеша от содержимого файла, чтобы избежать перезаписи и инъекций в путь.
  4. Проверку 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, чтобы разгрузить сервер приложения.