Активный
- Тема Автор
- #1
Загрузка файлов - важная функция веб-приложений. Разберем безопасную реализацию.
Базовая форма загрузки
Проверка типа файла
Проверка изображения
Множественная загрузка
Класс для загрузки файлов
Важные моменты:
- Всегда проверяйте тип файла
- Ограничивайте размер файлов
- Используйте безопасные имена файлов
- Проверяйте загружаемые изображения
- Храните файлы вне веб-корня когда возможно
Безопасная загрузка файлов защищает сервер!
Базовая форма загрузки
Код:
<!-- 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"];
}
?>
Важные моменты:
- Всегда проверяйте тип файла
- Ограничивайте размер файлов
- Используйте безопасные имена файлов
- Проверяйте загружаемые изображения
- Храните файлы вне веб-корня когда возможно
Безопасная загрузка файлов защищает сервер!