Загрузка файлов в PHP: полное руководство

Активный
Статус
Сообщения
516
Лайки
32

8

месяц на сайте

Загрузка файлов - важная функция веб-приложений. Разберем безопасную реализацию.

Базовая форма загрузки
Код:
<!-- upload_form.html -->
<form method="POST" action="upload.php" enctype="multipart/form-data">
    <input type="file" name="file" accept="image/*">
    <button type="submit">Загрузить</button>
</form>

<?php
// upload.php
if($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES["file"])) {
    $file = $_FILES["file"];
    
    // Проверка ошибок
    if($file["error"] !== UPLOAD_ERR_OK) {
        die("Ошибка загрузки файла");
    }
    
    // Проверка типа файла
    $allowedTypes = ["image/jpeg", "image/png", "image/gif"];
    $fileType = $file["type"];
    
    if(!in_array($fileType, $allowedTypes)) {
        die("Недопустимый тип файла");
    }
    
    // Проверка размера (5MB)
    $maxSize = 5 * 1024 * 1024;
    if($file["size"] > $maxSize) {
        die("Файл слишком большой");
    }
    
    // Безопасное имя файла
    $filename = basename($file["name"]);
    $filename = preg_replace("/[^a-zA-Z0-9._-]/", "", $filename);
    $target = "uploads/" . uniqid() . "_" . $filename;
    
    // Перемещение файла
    if(move_uploaded_file($file["tmp_name"], $target)) {
        echo "Файл загружен: " . $target;
    } else {
        die("Ошибка перемещения файла");
    }
}
?>

Проверка типа файла
Код:
<?php
function validateFileType($file) {
    // Проверка MIME типа
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mimeType = finfo_file($finfo, $file["tmp_name"]);
    finfo_close($finfo);
    
    $allowedTypes = ["image/jpeg", "image/png", "image/gif"];
    return in_array($mimeType, $allowedTypes);
}

// Проверка расширения
function validateFileExtension($filename) {
    $allowedExtensions = ["jpg", "jpeg", "png", "gif"];
    $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    return in_array($extension, $allowedExtensions);
}
?>

Проверка изображения
Код:
<?php
function validateImage($file) {
    // Проверка, что это действительно изображение
    $imageInfo = getimagesize($file["tmp_name"]);
    if($imageInfo === false) {
        return false;
    }
    
    // Проверка размеров
    $maxWidth = 2000;
    $maxHeight = 2000;
    
    if($imageInfo[0] > $maxWidth || $imageInfo[1] > $maxHeight) {
        return false;
    }
    
    return true;
}

// Изменение размера изображения
function resizeImage($source, $target, $maxWidth, $maxHeight) {
    $imageInfo = getimagesize($source);
    $width = $imageInfo[0];
    $height = $imageInfo[1];
    $type = $imageInfo[2];
    
    // Вычисление новых размеров
    $ratio = min($maxWidth / $width, $maxHeight / $height);
    $newWidth = $width * $ratio;
    $newHeight = $height * $ratio;
    
    // Создание изображения
    switch($type) {
        case IMAGETYPE_JPEG:
            $sourceImage = imagecreatefromjpeg($source);
            break;
        case IMAGETYPE_PNG:
            $sourceImage = imagecreatefrompng($source);
            break;
        case IMAGETYPE_GIF:
            $sourceImage = imagecreatefromgif($source);
            break;
        default:
            return false;
    }
    
    // Создание нового изображения
    $newImage = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
    
    // Сохранение
    imagejpeg($newImage, $target, 90);
    imagedestroy($sourceImage);
    imagedestroy($newImage);
    
    return true;
}
?>

Множественная загрузка
Код:
<?php
if($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES["files"])) {
    $files = $_FILES["files"];
    $uploadDir = "uploads/";
    
    foreach($files["error"] as $key => $error) {
        if($error == UPLOAD_ERR_OK) {
            $tmpName = $files["tmp_name"][$key];
            $name = $files["name"][$key];
            
            // Валидация
            if(validateFile($files, $key)) {
                $target = $uploadDir . uniqid() . "_" . basename($name);
                move_uploaded_file($tmpName, $target);
            }
        }
    }
}
?>

Класс для загрузки файлов
Код:
<?php
class FileUploader {
    private $allowedTypes = [];
    private $maxSize = 0;
    private $uploadDir = "";
    
    public function __construct($uploadDir, $allowedTypes = [], $maxSize = 5242880) {
        $this->uploadDir = $uploadDir;
        $this->allowedTypes = $allowedTypes;
        $this->maxSize = $maxSize;
        
        if(!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
    }
    
    public function upload($file) {
        // Проверка ошибок
        if($file["error"] !== UPLOAD_ERR_OK) {
            return ["success" => false, "error" => "Ошибка загрузки"];
        }
        
        // Проверка типа
        if(!empty($this->allowedTypes)) {
            if(!in_array($file["type"], $this->allowedTypes)) {
                return ["success" => false, "error" => "Недопустимый тип файла"];
            }
        }
        
        // Проверка размера
        if($file["size"] > $this->maxSize) {
            return ["success" => false, "error" => "Файл слишком большой"];
        }
        
        // Генерация имени
        $filename = $this->generateFilename($file["name"]);
        $target = $this->uploadDir . $filename;
        
        // Загрузка
        if(move_uploaded_file($file["tmp_name"], $target)) {
            return ["success" => true, "filename" => $filename, "path" => $target];
        }
        
        return ["success" => false, "error" => "Ошибка перемещения файла"];
    }
    
    private function generateFilename($originalName) {
        $extension = pathinfo($originalName, PATHINFO_EXTENSION);
        return uniqid() . "_" . time() . "." . $extension;
    }
}

// Использование
$uploader = new FileUploader("uploads/", ["image/jpeg", "image/png"], 5 * 1024 * 1024);
$result = $uploader->upload($_FILES["file"]);

if($result["success"]) {
    echo "Файл загружен: " . $result["filename"];
} else {
    echo "Ошибка: " . $result["error"];
}
?>

Важные моменты:
- Всегда проверяйте тип файла
- Ограничивайте размер файлов
- Используйте безопасные имена файлов
- Проверяйте загружаемые изображения
- Храните файлы вне веб-корня когда возможно

Безопасная загрузка файлов защищает сервер!
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху