Initial commit: Flutter 无书应用项目
This commit is contained in:
203
ht/api/upload.php
Normal file
203
ht/api/upload.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 图片上传处理API
|
||||
* 处理图片上传,支持自动调整大于1280宽度的图片为1024宽度
|
||||
*/
|
||||
|
||||
// 引入必要文件
|
||||
require_once '../inc/pubs.php';
|
||||
require_once '../inc/sqls.php';
|
||||
|
||||
// 验证用户登录状态
|
||||
if (!checkLogin()) {
|
||||
exit(json_encode([
|
||||
'code' => 1001,
|
||||
'msg' => '请先登录'
|
||||
]));
|
||||
}
|
||||
|
||||
// 检查请求方法
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
exit(json_encode([
|
||||
'code' => 1002,
|
||||
'msg' => '请求方法错误'
|
||||
]));
|
||||
}
|
||||
|
||||
// 检查是否有文件上传
|
||||
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
|
||||
exit(json_encode([
|
||||
'code' => 1003,
|
||||
'msg' => '上传失败: ' . uploadErrorMessage($_FILES['image']['error'])
|
||||
]));
|
||||
}
|
||||
|
||||
// 验证文件类型
|
||||
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||
$fileType = $_FILES['image']['type'];
|
||||
|
||||
if (!in_array($fileType, $allowedTypes)) {
|
||||
exit(json_encode([
|
||||
'code' => 1004,
|
||||
'msg' => '只允许上传JPG、PNG、GIF和WEBP格式的图片'
|
||||
]));
|
||||
}
|
||||
|
||||
// 验证文件大小(最大10MB)
|
||||
$maxFileSize = 10 * 1024 * 1024; // 10MB
|
||||
if ($_FILES['image']['size'] > $maxFileSize) {
|
||||
exit(json_encode([
|
||||
'code' => 1005,
|
||||
'msg' => '文件大小超过限制,最大允许10MB'
|
||||
]));
|
||||
}
|
||||
|
||||
// 准备上传路径
|
||||
$uploadDir = '../uploads/';
|
||||
if (!file_exists($uploadDir)) {
|
||||
mkdir($uploadDir, 0777, true);
|
||||
}
|
||||
|
||||
// 生成唯一文件名
|
||||
$extension = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
|
||||
$fileName = uniqid('img_') . '_' . date('Ymd') . '.' . $extension;
|
||||
$uploadPath = $uploadDir . $fileName;
|
||||
$relativeUrl = 'uploads/' . $fileName;
|
||||
|
||||
// 处理图片上传
|
||||
$uploaded = false;
|
||||
|
||||
// 获取图片信息
|
||||
$imageInfo = getimagesize($_FILES['image']['tmp_name']);
|
||||
if (!$imageInfo) {
|
||||
exit(json_encode([
|
||||
'code' => 1006,
|
||||
'msg' => '无效的图片文件'
|
||||
]));
|
||||
}
|
||||
|
||||
$width = $imageInfo[0];
|
||||
$height = $imageInfo[1];
|
||||
|
||||
// 如果图片宽度大于1280,则调整为1024宽度(尽管前端已经处理,这里作为后端保障)
|
||||
if ($width > 1280) {
|
||||
// 计算新高度,保持比例
|
||||
$newWidth = 1024;
|
||||
$newHeight = intval($height * ($newWidth / $width));
|
||||
|
||||
// 根据图片类型创建图像
|
||||
switch ($imageInfo[2]) {
|
||||
case IMAGETYPE_JPEG:
|
||||
$source = imagecreatefromjpeg($_FILES['image']['tmp_name']);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
$source = imagecreatefrompng($_FILES['image']['tmp_name']);
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
$source = imagecreatefromgif($_FILES['image']['tmp_name']);
|
||||
break;
|
||||
case IMAGETYPE_WEBP:
|
||||
$source = imagecreatefromwebp($_FILES['image']['tmp_name']);
|
||||
break;
|
||||
default:
|
||||
exit(json_encode([
|
||||
'code' => 1007,
|
||||
'msg' => '不支持的图片格式'
|
||||
]));
|
||||
}
|
||||
|
||||
// 创建新图像
|
||||
$thumb = imagecreatetruecolor($newWidth, $newHeight);
|
||||
|
||||
// 保持PNG和WebP的透明度
|
||||
if ($imageInfo[2] == IMAGETYPE_PNG || $imageInfo[2] == IMAGETYPE_WEBP) {
|
||||
imagealphablending($thumb, false);
|
||||
imagesavealpha($thumb, true);
|
||||
$transparent = imagecolorallocatealpha($thumb, 255, 255, 255, 127);
|
||||
imagefilledrectangle($thumb, 0, 0, $newWidth, $newHeight, $transparent);
|
||||
}
|
||||
|
||||
// 调整图像大小
|
||||
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
||||
|
||||
// 保存图像
|
||||
switch ($imageInfo[2]) {
|
||||
case IMAGETYPE_JPEG:
|
||||
$uploaded = imagejpeg($thumb, $uploadPath, 90);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
$uploaded = imagepng($thumb, $uploadPath, 9);
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
$uploaded = imagegif($thumb, $uploadPath);
|
||||
break;
|
||||
case IMAGETYPE_WEBP:
|
||||
$uploaded = imagewebp($thumb, $uploadPath, 90);
|
||||
break;
|
||||
}
|
||||
|
||||
// 释放内存
|
||||
imagedestroy($source);
|
||||
imagedestroy($thumb);
|
||||
} else {
|
||||
// 直接移动上传的文件
|
||||
$uploaded = move_uploaded_file($_FILES['image']['tmp_name'], $uploadPath);
|
||||
}
|
||||
|
||||
// 检查上传是否成功
|
||||
if (!$uploaded) {
|
||||
exit(json_encode([
|
||||
'code' => 1008,
|
||||
'msg' => '文件保存失败'
|
||||
]));
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
$user = $_SESSION['user'];
|
||||
$ip = "".$_SERVER['REMOTE_ADDR'];
|
||||
$db = new DB();
|
||||
$db->insert('logs', [
|
||||
'user_id' => $user['id'],
|
||||
'action' => '上传图片',
|
||||
'idesc' => '上传了图片: ' . $fileName,
|
||||
'ip' => $ip,
|
||||
'logtime' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
// 返回成功信息和图片URL
|
||||
exit(json_encode([
|
||||
'code' => 0,
|
||||
'msg' => '上传成功',
|
||||
'data' => [
|
||||
'url' => $relativeUrl,
|
||||
'width' => $width,
|
||||
'height' => $height
|
||||
]
|
||||
]));
|
||||
|
||||
/**
|
||||
* 获取上传错误消息
|
||||
* @param int $errorCode 上传错误代码
|
||||
* @return string 错误消息
|
||||
*/
|
||||
function uploadErrorMessage($errorCode) {
|
||||
switch ($errorCode) {
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
return '上传的文件超过了php.ini中upload_max_filesize指令限制的大小';
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
return '上传的文件超过了HTML表单中MAX_FILE_SIZE指令指定的大小';
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
return '文件只有部分被上传';
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
return '没有文件被上传';
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
return '找不到临时文件夹';
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
return '文件写入失败';
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
return '文件上传被PHP扩展程序中断';
|
||||
default:
|
||||
return '未知上传错误';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user