Php 内存下载和解压缩zip存档

Php 内存下载和解压缩zip存档,php,zip,unzip,Php,Zip,Unzip,我想下载一个zip档案,并使用PHP在内存中解压 这就是我今天所拥有的(对我来说,文件处理太多了:): 您可以将流获取到zip中的文件,并将其解压缩到变量中: $fp = $zip->getStream('test.txt'); if(!$fp) exit("failed\n"); while (!feof($fp)) { $contents .= fread($fp, 1024); } fclose($fp); 警告:这无法在内存中完成-ZipArchive无法使用“内存映

我想下载一个zip档案,并使用PHP在内存中解压

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


您可以将流获取到zip中的文件,并将其解压缩到变量中:

$fp = $zip->getStream('test.txt');
if(!$fp) exit("failed\n");

while (!feof($fp)) {
    $contents .= fread($fp, 1024);
}

fclose($fp);
警告:这无法在内存中完成-
ZipArchive
无法使用“内存映射文件”

您可以将zip文件中的文件数据获取到变量(内存)中,因为它支持:

您只能使用
zip://
或通过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);

如果您可以使用系统调用,最简单的方法应该如下所示(bzip2案例)。你只需要使用stdout

$out=shell_exec('bzip2 -dkc '.$zip);
简单到:

$zipFile = "test.zip";
$fileInsideZip = "somefile.txt";
$content = file_get_contents("zip://$zipFile#$fileInsideZip");

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

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

function GetZipContent(String $body_containing_zip_file) {

    $sectors = explode("\x50\x4b\x01\x02", $data);
    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;
}

希望这是有用的…

如何下载文件并将其“管道”到
$zip
?不,
zip://
目前只支持本地文件(以及ZipArchive)。您必须通过标准文件系统访问它。将更新答案以使您的
http
url可见。不,不支持堆叠流,我想即使
文件://
也不起作用。它需要是文件系统的路径。对于
ZipArchive
类也一样,我假设这是相互关联的。在zip PHP扩展中,流没有得到很好的支持,这在我看来有点遗憾。使用tempfile来解决这个问题,第二个代码示例。您可以将其封装到它自己的扩展/装饰ZipArchive类中,并提供一个文件系统包装器,使其更流畅。@dacwe:如果您的文件系统装载了一个ramdisk,那么让
ZipArchive
在内存中工作根本没有问题——重要的是:)是的,这实际上是我解决问题的方法,但它不是一个php解决方案:)
$zipFile = "test.zip";
$fileInsideZip = "somefile.txt";
$content = file_get_contents("zip://$zipFile#$fileInsideZip");
function GetZipContent(String $body_containing_zip_file) {

    $sectors = explode("\x50\x4b\x01\x02", $data);
    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;
}