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

PHP技术求助:HTTP响应二进制ASCII转ZIP文件及多附件POST请求ZIP解析失败问题

我来帮你梳理下排查方向和解决方案,你遇到的问题大概率是数据提取错误或者代码逻辑的小疏漏,咱们一步步拆解:

一、先排查提取的ZIP二进制数据是否准确

你是手动拆分MIME请求的,这一步很容易踩坑:

  • 有没有误把MIME边界、头部字段(比如Content-Type: application/zip这类行)包含进了$zipBinary里?正常ZIP文件的开头是十六进制504B0304(对应ASCII的PK..),你可以用bin2hex(substr($zipBinary, 0, 4))输出开头字符,对比下是不是这个值——如果前面有换行、空格或者其他字符,说明数据提取错了。
  • 检查数据完整性:用strlen($zipBinary)对比原始test.zip文件的大小,如果长度不一致,说明数据被截断了。另外正常ZIP文件的结尾是十六进制504B0506,你可以检查下数据尾部有没有这个标记。

二、修复代码里的两个关键问题

你的unzip函数有两个容易忽略的错误,哪怕数据是对的,也会导致ZIP无法读取:

1. 错误的ZIP打开模式

你用了ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE,这两个参数是用来创建/覆盖ZIP文件的,不是读取已有文件!用这个模式打开已存在的ZIP,会清空原文件内容,自然numFiles会返回0。

正确的姿势是用只读模式打开:

$res = $zip->open($file, ZIPARCHIVE::RDONLY);

甚至可以省略第二个参数,默认就是只读模式。

2. 文件写入的模式问题

file_put_contents在Windows环境下可能会把二进制字符(比如0x0A)转成换行符0x0D0A,破坏ZIP的二进制结构。建议换成明确的二进制写入模式:

// 替换原来的file_put_contents
$handle = fopen($file, 'wb');
fwrite($handle, $zipBinary);
fclose($handle);

'wb'模式确保完全按二进制写入,不会做任何字符转换,跨平台更稳妥。

三、优化临时文件路径

你用tempnam("tmp", "zip")的相对路径,可能存在权限问题或者找不到目录的情况,换成系统临时目录更可靠:

$file = tempnam(sys_get_temp_dir(), "zip");

sys_get_temp_dir()会返回系统默认的临时目录,权限一般都是没问题的。

调试小技巧

  • 先注释掉unlink($file),把生成的临时文件保留下来,用7-Zip/WinRAR打开试试,或者在Unix系统下用file 临时文件名命令查看文件类型——如果输出不是Zip archive data,说明数据肯定有问题。
  • 在$zip->open失败时,可以输出错误码(ZipArchive有ER_*系列常量),比如error_log("ZIP打开失败,错误码:{$res}"),能帮你快速定位问题(比如ER_NOZIP就是文件不是有效的ZIP)。

修改后的完整函数示例

public static function unzip($zipBinary) {
    $zip = new ZipArchive;
    // 使用系统临时目录创建临时文件
    $file = tempnam(sys_get_temp_dir(), "zip");
    
    // 二进制模式写入数据
    $handle = fopen($file, 'wb');
    fwrite($handle, $zipBinary);
    fclose($handle);
    
    // 只读模式打开已有ZIP文件
    $res = $zip->open($file, ZIPARCHIVE::RDONLY);
    if ($res === TRUE) {
        $files = [];
        for ($i = 0; $i < $zip->numFiles; $i++) {
            $files[$zip->getNameIndex($i)] = $zip->getFromIndex($i);
        }
        $zip->close();
        unlink($file);
        return $files;
    } else {
        error_log("ZIP文件打开失败,错误码:{$res}");
        unlink($file);
        return false;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:17:29