PHP

Загрузка файлов с проверками

Algonexys · 07.08.2026 · 👁 0

Проверка реального MIME-типа, размера и генерация безопасного имени — минимум для безопасной загрузки.

Код

<?php
declare(strict_types=1);

const MAX_SIZE  = 5 * 1024 * 1024;                      // 5 МБ
const ALLOWED   = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
const UPLOAD_DIR = __DIR__ . '/uploads';

function handleUpload(array $file): string
{
    if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
        throw new RuntimeException('Ошибка загрузки: код ' . $file['error']);
    }
    if ($file['size'] > MAX_SIZE) {
        throw new RuntimeException('Файл больше 5 МБ');
    }
    if (!is_uploaded_file($file['tmp_name'])) {
        throw new RuntimeException('Недопустимый источник файла');
    }

    // Реальный тип по содержимому, а не по имени и не по $_FILES['type']
    $mime = (new finfo(FILEINFO_MIME_TYPE))->file($file['tmp_name']);
    if (!isset(ALLOWED[$mime])) {
        throw new RuntimeException('Недопустимый тип файла: ' . $mime);
    }

    $name = bin2hex(random_bytes(16)) . '.' . ALLOWED[$mime];
    $path = UPLOAD_DIR . '/' . $name;

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