附件:支持视频 / 文档上传,可预览的浏览器直接看,预览不了的给下载
之前节点附件只能传图片和 PDF(accept 过滤 + 20MB 上限),视频传不上来。 本批放开:MP4 / MOV / PDF / Word / Excel / ZIP 都能作为附件上传, 仍走同一份 Uploads::handleFiles(MIME 白名单三层识别不变),存进已配置的 OSS。 大小分级:照片仍走 photo_max_mb(管理员可调),视频与文档放宽到 40MB (Uploads::MAX_FILE_BYTES,给线上 post_max_size=50M 留余量),先 detect 再按 is_image 选上限。前端 form.php / attachments.php 同步拦截并按类型细分暂存区图标。 预览走灯箱四类型视图:图片(img)/ 视频(<video>,配合 media/show 新增的 HTTP Range 单区间 206/416,进度条可拖、Safari 也能播)/ PDF(iframe 内嵌 阅读器)/ 其它(Word / ZIP 等浏览器预览不了 → 灯箱里给下载按钮)。 dl=1 下载不接 Range;多区间回退 200 全量。 已验证:本地全链 11 步全绿(渲染检查 308 项、表单交互 73 项); 远端 e2e 0 失败(新增 mp4 上传落库 video/mp4、Range 206/416/后缀区间/ 多区间回退/dl 不接 Range 专项断言);部署后双 PHP 渲染逐字节一致。
This commit is contained in:
+20
-8
@@ -20,9 +20,17 @@ final class Uploads
|
||||
/** 单次请求最多处理的文件数,防止一次拖几百个把请求拖死 */
|
||||
public const MAX_FILES = 30;
|
||||
|
||||
/** 单文件硬上限 */
|
||||
/** 单文件硬上限(兜底值;实际限制见 handleFiles 里的分级逻辑) */
|
||||
public const MAX_BYTES = 20971520; // 20MB
|
||||
|
||||
/**
|
||||
* 非图片文件(视频 / PDF / Word 等)的单文件上限。
|
||||
* 视频普遍比照片大,20MB 根本不够用;但这再大也大不过服务器的
|
||||
* post_max_size(超了整个请求会被 PHP 静默丢弃),所以取 40MB,
|
||||
* 给 50M 的 post_max_size 留出表单字段的余量。
|
||||
*/
|
||||
public const MAX_FILE_BYTES = 41943040; // 40MB
|
||||
|
||||
/**
|
||||
* 把 php.ini 里的 "8M" / "50M" 这类写法换算成字节数。
|
||||
*
|
||||
@@ -89,20 +97,24 @@ final class Uploads
|
||||
$errors[] = $file['name'] . ':上传错误(码 ' . $file['error'] . ')';
|
||||
continue;
|
||||
}
|
||||
$limit = $photoMax > 0 ? max($photoMax, self::MAX_BYTES) : self::MAX_BYTES;
|
||||
if ($file['size'] > $limit) {
|
||||
$errors[] = $file['name'] . ':超过大小上限';
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 先识别类型再限大小:图片走管理员设的 photo_max_mb(12MB),
|
||||
视频 / PDF / Word 等非图片走更宽的 MAX_FILE_BYTES(40MB)。
|
||||
detectFile 只读文件头 32 字节,先跑也不费。 */
|
||||
$info = Mime::detectFile($file['tmp_name'], $file['name']);
|
||||
$mime = $info['mime'];
|
||||
if ($mime === null || !isset(Mime::ALLOWED[$mime])) {
|
||||
$errors[] = $file['name'] . ':不支持的文件类型';
|
||||
continue;
|
||||
}
|
||||
if ($info['is_image'] && $photoMax > 0 && $file['size'] > $photoMax) {
|
||||
$errors[] = $file['name'] . ':照片超过 ' . (int)Settings::get('photo_max_mb') . 'MB';
|
||||
if ($info['is_image']) {
|
||||
$limit = $photoMax > 0 ? $photoMax : self::MAX_BYTES;
|
||||
if ($file['size'] > $limit) {
|
||||
$errors[] = $file['name'] . ':照片超过 ' . (int)Settings::get('photo_max_mb') . 'MB';
|
||||
continue;
|
||||
}
|
||||
} elseif ($file['size'] > self::MAX_FILE_BYTES) {
|
||||
$errors[] = $file['name'] . ':文件超过 ' . (int)(self::MAX_FILE_BYTES / 1048576) . 'MB';
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user