在内存中下载并解压缩zip存档

dac*_*cwe 9 php zip unzip

我想下载一个zip存档,并使用PHP将其解压缩到内存中.

这就是我今天所拥有的(而且对我来说文件处理太多:)):

// download the data file from the real page
copy("http://www.curriculummagic.com/AdvancedBalloons.kmz", "./data/zip.kmz");

// unzip it
$zip = new ZipArchive;
$res = $zip->open('./data/zip.kmz');
if ($res === TRUE) {
    $zip->extractTo('./data');
    $zip->close();
}

// use the unzipped files...
Run Code Online (Sandbox Code Playgroud)

hak*_*kre 16

警告:这不能在内存中完成 - ZipArchive无法使用"内存映射文件".

您可以使用file_get_contentsDocs将zip文件中的文件数据获取到变量(内存)中,因为它支持zip://Stream包装器文档:

$zipFile = './data/zip.kmz';     # path of zip-file
$fileInZip = 'test.txt';         # name the file to obtain

# read the file's data:
$path = sprintf('zip://%s#%s', $zipFile, $fileInZip);
$fileData = file_get_contents($path);
Run Code Online (Sandbox Code Playgroud)

您只能zip://通过ZipArchive或通过ZipArchive 访问本地文件.为此,您可以先将内容复制到临时文件并使用它:

$zip = 'http://www.curriculummagic.com/AdvancedBalloons.kmz';
$file = 'doc.kml';

$ext = pathinfo($zip, PATHINFO_EXTENSION);
$temp = tempnam(sys_get_temp_dir(), $ext);
copy($zip, $temp);
$data = file_get_contents("zip://$temp#$file");
unlink($temp);
Run Code Online (Sandbox Code Playgroud)


小智 5

老话题但仍然相关,因为我问自己同样的问题,但没有找到答案。

我最终编写了这个函数,它返回一个数组,其中包含存档中包含的每个文件的名称以及该文件的解压缩内容:

function GetZipContent(String $body_containing_zip_file) {

    $sectors = explode("\x50\x4b\x01\x02", $body_containing_zip_file);
    array_pop($sectors);
    $files = explode("\x50\x4b\x03\x04", implode("\x50\x4b\x01\x02", $sectors));
    array_shift($files);

    $result = array();
    foreach($files as $file) {
        $header = unpack("vversion/vflag/vmethod/vmodification_time/vmodification_date/Vcrc/Vcompressed_size/Vuncompressed_size/vfilename_length/vextrafield_length", $file);
        array_push($result, [
            'filename' => substr($file, 26, $header['filename_length']),
            'content' => gzinflate(substr($file, 26 + $header['filename_length'], -12))
        ]);
    }
    
    return $result;
}
Run Code Online (Sandbox Code Playgroud)