You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

上传至服务器前如何验证文件是否为归档文件?

验证上传归档文件的可行方案

为什么$my_image['type']不靠谱

浏览器返回的type字段是根据文件名后缀推断的,并非读取文件真实内容,所以RAR这类格式经常会被识别为application/octet-stream,完全不能作为可靠验证依据。

具体验证步骤

1. 文件名后缀初步过滤(第一道防线)

先通过后缀筛选常见归档格式,虽然可以被篡改,但能快速拦截大部分误传:

$allowed_extensions = ['rar', 'zip', '7z', 'tar', 'gz'];
$file_ext = strtolower(pathinfo($_FILES['archive']['name'], PATHINFO_EXTENSION));

if (!in_array($file_ext, $allowed_extensions)) {
    exit('请上传RAR/ZIP/7Z等格式的归档文件');
}

2. 读取文件魔术数字验证真实格式(核心验证)

每种归档格式都有固定的文件头魔术数字,读取临时文件的前几个字节就能判断真实类型,这是最可靠的方式:

$temp_file_path = $_FILES['archive']['tmp_name'];
// 读取文件前8字节(足够覆盖主流归档格式的魔术数字)
$file_header = file_get_contents($temp_file_path, false, null, 0, 8);
$hex_header = bin2hex($file_header);

// 主流归档格式的魔术数字(十六进制)
$valid_magic_numbers = [
    '526172211a0700', // RAR
    '504b0304',       // ZIP
    '377abcaf271c',   // 7Z
    '7573746172',     // TAR
    '1f8b08'          // GZIP
];

$is_valid = false;
foreach ($valid_magic_numbers as $magic) {
    if (str_starts_with($hex_header, $magic)) {
        $is_valid = true;
        break;
    }
}

if (!$is_valid) {
    // 删除非法临时文件
    unlink($temp_file_path);
    exit('上传的文件不是合法的归档文件');
}

3. 进阶验证:尝试打开归档文件(高安全要求场景)

如果需要确保归档文件可正常读取,可以用PHP扩展尝试打开,能成功打开则说明是有效归档:

  • ZIP格式验证(依赖PHP内置ZipArchive扩展):
$zip = new ZipArchive();
if ($zip->open($temp_file_path) !== ZipArchive::OK) {
    unlink($temp_file_path);
    exit('无效的ZIP归档文件');
}
$zip->close();
  • RAR格式验证(需安装rar扩展):
if (!extension_loaded('rar')) {
    exit('服务器未启用RAR文件支持');
}
$rar = RarArchive::open($temp_file_path);
if (!$rar) {
    unlink($temp_file_path);
    exit('无效的RAR归档文件');
}
$rar->close();

注意:所有验证都必须在文件上传到服务器临时目录后执行,前端无法在上传前读取文件内容做真实验证,前端的后缀检查只能作为辅助,不能替代后端验证。

内容的提问来源于stack exchange,提问作者B23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:16:13